39

如何强制输入到 iPhone 上的文本框中的字符为大写?

4

11 回答 11

52

设置autocapitalizationType为。UITextAutocapitalizationTypeAllCharacters_UITextField

有关详细信息,请参阅UITextInputTraits 协议(由 UITextField 采用)

于 2010-01-08T11:30:58.713 回答
36

这个解决方案并不完全令人满意。

即使autocapitalizationType设置为UITextAutocapitalizationTypeAllCharacters,用户仍然可以按下大写字母来释放大写锁定。并且textField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]; return NO;解决方案不是很好:如果用户编辑文本的中间(在 a 之后textField.text =,编辑光标移动到字符串的末尾),我们会丢失编辑点。

我已经混合了这两种解决方案,这就是我的建议:设置UITextAutocapitalizationTypeAllCharacters,并将以下代码添加到UITextField.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {

    // Check if the added string contains lowercase characters.
    // If so, those characters are replaced by uppercase characters.
    // But this has the effect of losing the editing point
    // (only when trying to edit with lowercase characters),
    // because the text of the UITextField is modified.
    // That is why we only replace the text when this is really needed.
    NSRange lowercaseCharRange;
    lowercaseCharRange = [string rangeOfCharacterFromSet:[NSCharacterSet lowercaseLetterCharacterSet]];

    if (lowercaseCharRange.location != NSNotFound) {

        textField.text = [textField.text stringByReplacingCharactersInRange:range
                                                                 withString:[string uppercaseString]];
        return NO;
    }

    return YES;
}
于 2011-06-07T13:06:06.007 回答
33

虽然所有其他答案确实有效(它们使输入大写),但它们都存在未保留光标位置的问题(尝试在现有文本的中间插入一个字符)。这显然发生在UITextField'stext属性的设置器中,我还没有找到以编程方式恢复它的方法(例如,恢复原件selectedTextRange不起作用)。

然而,好消息是,有一种直接的方法来替换 a UITextField(或UITextView's)文本的一部分,它不会受到这个问题的影响:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    // not so easy to get an UITextRange from an NSRange...
    // thanks to Nicolas Bachschmidt (see http://stackoverflow.com/questions/9126709/create-uitextrange-from-nsrange)
    UITextPosition *beginning = textField.beginningOfDocument;
    UITextPosition *start = [textField positionFromPosition:beginning offset:range.location];
    UITextPosition *end = [textField positionFromPosition:start offset:range.length];
    UITextRange *textRange = [textField textRangeFromPosition:start toPosition:end];

    // replace the text in the range with the upper case version of the replacement string
    [textField replaceRange:textRange withText:[string uppercaseString]];

    // don't change the characters automatically
    return NO;
}

有关这些方法的更多信息,请参阅UITextInput.

于 2012-11-14T21:54:45.943 回答
2

与其测试字符是大写还是小写,不如假设它是小写。简单得多。

在里面

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string

方法:

NSString *newString = [[textField.text stringByAppendingString:string] uppercaseString];
textField.text = newString;

return NO;
于 2012-09-07T19:22:01.400 回答
2

这是我的代码,当我有 6 个文本字段时

希望你能明白这一点

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if (textField==self.textField6) {
        self.textField6.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]];
        return NO;
    }
    return YES;
}
于 2014-04-01T12:57:38.597 回答
2

最简单的方法是,实现文本字段的编辑更改方法并将文本字段的文本值设置为输入文本的大写表示

- (IBAction)TextFieldEditingChanged:(id)sender
{
    _yourTextField.text = [_yourTextField.text uppercaseString];
}
于 2014-08-07T18:48:53.997 回答
2

我从以前的答案中受到启发(谢谢),但他们都对我有一些缺陷:

  • 当您还想要小写甚至更多控制时,使用 textField.autocapitalizationType 并没有帮助。
  • textField.text = "my String" 将光标设置到 textField 的末尾,这在编辑时真的很烦人。

所以这是我的 Swift 代码,它可以让您完全控制输入的字符(大写、小写、忽略...)并让光标在您期望的位置。该代码经过测试可与多个文本字段一起使用。

编辑:使用 iOS 8.3 测试

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    // modify string as and if the user wants:
    // at this place you can also return false to ignore the replacement completely.
    var str = string
    if !Defaults.isUpperOrLower() {
        if Defaults.isAllLetterUpper() {
            str = string.uppercaseString
        } else {
            str = string.lowercaseString
        }
    }

    // updating textField.text sets the curser position to the end
    // so we store the cursor position before updating.
    let selRange = textField.selectedTextRange

    // Update textField as requested and modified.
    var txt = textField.text as NSString
    textField.text = txt.stringByReplacingCharactersInRange(range, withString: str)

    // recalculate and set the cursor position in the textField:
    // tested with
    // 1. typing a character
    // 2. backspace
    // 3. selecting a range + backspace
    // 4. selecting a range + typing a character
    if let selRange = selRange {
        var newPosition: UITextPosition?
        if range.length == 0 {
            // normal character
            newPosition = textField.positionFromPosition(selRange.end, inDirection: UITextLayoutDirection.Right, offset: count(string))
        } else {
            // backspace
            newPosition = textField.positionFromPosition(selRange.end, inDirection: UITextLayoutDirection.Left, offset: range.length - count(string))
        }
        textField.selectedTextRange = textField.textRangeFromPosition(newPosition, toPosition: newPosition)
    }

    // return false because we did everything manually
    return false
}
于 2015-05-03T20:56:58.567 回答
1

return NO 将有返回按钮的问题;

最好用这个

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    if ([[string uppercaseString] isEqualToString:string]) {
        return YES;
    }

    NSString *newString = [[textField.text stringByAppendingString:string] uppercaseString];
    textField.text = newString;
    return NO;

}
于 2015-01-14T09:13:41.973 回答
1

也许我还没有找到这种方法的所有问题,但到目前为止它对我来说效果很好。如果您沿着从-textField:shouldChangeCharactersInRange:replacementString:返回NO的路线走下去,似乎可以避免将选择跳到最后的问题。由于 UITextField 符合 UIKeyInput,只需重写方法-insertText:以在使用大写字符串调用 super 之前将输入字符串更改为大写:

- (void)insertText:(NSString *)text {
    NSString *uppercaseText = [text uppercaseString]
    [super insertText:uppercaseText]
}

或者,如果您已经迁移到 Swift:

override func insertText(text: String) {
    let uppercaseText = text.uppercaseString
    super.insertText(uppercaseText)
}
于 2015-02-20T04:40:19.470 回答
0

在文本字段中自动输入大写:

案例1:添加UITextDelegate协议,实现如下方法

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    textField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string capitalizedString]];

    return NO;
}

案例 2:在视图控制器的 ViewDidLoad() 方法中设置以下参数。尽管在这种情况下,用户可以关闭键盘上的大写按钮。

urTextFieldName.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
于 2014-05-18T01:54:09.287 回答
0

我对上述一些答案的一个问题是,如果您尝试设置textfield.text,您将丢失光标位置。所以如果用户试图编辑文本的中间部分,光标会跳到末尾

这是我的简单 Swift 解决方案,仍在使用UITextFieldDelegate

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    if textField == textFieldToUppercase {
        if string == "" {
            // User presses backspace
            textField.deleteBackward()
        } else {
            // User presses a key or pastes
            textField.insertText(string.uppercaseString)
        }
        // Do not let specified text range to be changed
        return false
    }

    return true
}

如果用户按下键盘上的ReturnDone等键,您仍然需要处理。只需添加:

if string == "\n" {
    // Do something when 'Done' is pressed, like dismiss the keyboard
    textField.resignFirstResponder()
    return false
}

……在里面func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool

于 2016-06-09T05:39:59.190 回答