hungbm06
hungbm06

Reputation: 1549

iPhone Force Textbox Input to Upper Case

How do I force characters input into a textbox on the iPhone to upper case?

Upvotes: 39

Views: 23660

Answers (11)

Dan
Dan

Reputation: 309

One issue I have with some of the above answers is if you try and set textfield.text, you will lose the cursor position. So if a user tries to edit the middle of the text, the cursor will jump to the end.

Here is my simple Swift solution, still using 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
}

You still have to handle if a user presses the Return, Done, etc key on the keyboard. Just add:

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

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

Upvotes: 0

user2929279
user2929279

Reputation: 27

To Automatically input uppercase in textfield:

Case 1: Add UITextDelegate protocol and implement the following method

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

    return NO;
}

Case 2:Set the following parameter in the ViewDidLoad() method in your view controller. Although in this case the user can turnoff the caps button on the keyboard.

urTextFieldName.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;

Upvotes: 0

user2021505
user2021505

Reputation: 292

This is my code, when i have 6 textFields

Hope you will get the point

- (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;
}

Upvotes: 2

Gerd Castan
Gerd Castan

Reputation: 6849

I've been inspired by previous answers (thanks), but all of them had some flaws for me:

  • using textField.autocapitalizationType does not help when you also want lowercase or even more control.
  • textField.text = "my String" sets the cursor to the end of the textField which is really annoying when editing.

So this is my Swift code that gives you full control over the typed characters (uppercase, lowercase, ignore...) AND lets the cursor where you expect it. The code is tested to work with more than one textField.

Edit: tested with 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
}

Upvotes: 2

Christopher Weems
Christopher Weems

Reputation: 11

Maybe I haven't found all the kinks to this method, but so far it works well for me. It seems to avoid the issues with jumping selection to the end if you go down the route of returning NO from -textField:shouldChangeCharactersInRange:replacementString:. Since UITextField conforms to UIKeyInput, simply override the method -insertText: to change the input string to uppercase before calling super with the uppercase string:

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

Or if you've moved along to Swift:

override func insertText(text: String) {
    let uppercaseText = text.uppercaseString
    super.insertText(uppercaseText)
}

Upvotes: 1

Ashish Srivastava
Ashish Srivastava

Reputation: 101

return NO will have issues with back button;

beter use this

- (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;

}

Upvotes: 1

Omkar Guhilot
Omkar Guhilot

Reputation: 1698

The simplest way would be to , implement the editing changed method of the text field and set the textfield's text value to upper case representation of the entered text

- (IBAction)TextFieldEditingChanged:(id)sender
{
    _yourTextField.text = [_yourTextField.text uppercaseString];
}

Upvotes: 2

Daniel Rinser
Daniel Rinser

Reputation: 8855

While all the other answers do actually work (they make the input uppercase), they all have the problem that the cursor position is not retained (try inserting a character in the middle of the existing text). This apparently happens in the setter of UITextField's text property, and I have not found a way to restore it programmatically (for example, restoring the original selectedTextRange does not work).

However, the good news is, that there is a direct way to replace parts of a UITextField's (or UITextView's) text, which does not suffer from this issue:

- (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;
}

For further information on these methods, see the documentation of UITextInput.

Upvotes: 33

jay492355
jay492355

Reputation: 594

Rather than test for whether the character is upper- or lower-case, just assume that it's lower case. Much simpler.

In the

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

method:

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

return NO;

Upvotes: 2

MonsieurDart
MonsieurDart

Reputation: 6035

This solution is not fully satisfying.

Even with the autocapitalizationType set to UITextAutocapitalizationTypeAllCharacters, the user can still press caps to release the caps lock. And the textField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]; return NO; solution is not that great: we loose the editing point if the user edits the middle of the text (after a textField.text =, the editing cursor goes to the end of the string).

I've done a mix of the two solution and here is what I propose: set UITextAutocapitalizationTypeAllCharacters, and add the following code to the delegate of the 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;
}

Upvotes: 36

Adam Woś
Adam Woś

Reputation: 2473

Set autocapitalizationType to UITextAutocapitalizationTypeAllCharacters on the UITextField.

See UITextInputTraits protocol (adopted by UITextField) for more details.

Upvotes: 52

Related Questions