Wednesday, March 25, 2009

Limiting Text Field Input

Received a question today about how to make a UITextField so that it can only accept a certain number of characters of input. Say, you wanted a text field that only allows up to five characters to be entered, and then accepts no more. It's actually easy.

First step is to set your controller (or other appropriate class) as the text field's delegate. You should conform that class to the UITextFieldDelegate protocol, and then do something like this:
myTextField.delegate = self
You can also set the delegate in Interface Builder by control-dragging from the text field to File's Owner or some other object instance, and selecting the delegate outlet.

After that, you just need to implement a delegate method to limit the input.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
return !([newString length] > 5);
}


You can replace "5" with whatever value, variable, or constant is appropriate for your situation. Whenever we return NO from this delegate method, the pending edit is cancelled.



16 comments:

Cyril said...

You know what? I was asking myself that question just this morning! Didn't have time to look for the solution yet, and you beat me to the finish line... That IS incredible. Just like @timhaines alway finding your blog in his searches....

Thanks Jeff

Jeff LaMarche said...

Shh... don't tell anyone, but I'm psychic. ;)

GrouchoDuke said...

That's a great chunk of code! Expect it in the next version of my app. Thanks!

cory said...

- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:
I'm doing it ever so slightly differently, but it's pretty flexible when you have a small set of characters you want the user to be able to enter (e.g. 0-9 and .)


(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet];
return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0);
}

kev said...

Thanks for the tip.

Sorry if this is a bit of a newb question, but if i have multiple text fields in a view, how would I use this to enforce different limitations for each? Right now I have both UITextFields delegated to the view controller class but I can't seem to figure out how I can separate it out.

Any help is appreciated!

Brian said...

I used the second way with my project (the example limiting text entry to 0-9 and .), but that way doesn't allow the user to delete their entry. Does anyone know how to fix this problem?

jm said...

Awesome, just want I was looking for, thank you.

Now, I'm trying to do the same, for 2 different UITextFields within the same view, each with their own character limit... could you give me a hint please?

Dj said...

very helpful, thanks! can anybody point me to a good example of how to take the textinput and act upon the characters entered? ie. if "abc" is type...then buttons "a", "b" and "c" will appear...i'm taking the input as an nsstring...but i guess i'd have to use an array ?

Julian said...

Yes, I'd love to know how to make this work with multiple text fields. An update to the example or a second blog post would be much appreciated.

danhvidding said...

Very helpful, thanks for sharing.

Edwin said...

scrub m65 kamagra attorney lawyer body scrub field jacket lovegra marijuana attorney injury lawyer

JeansPilot said...

JeansPilot offers the chance to buy a large variety of men’s and women’s jeans clothing from the world famous Italian Brands.
Online jeans clothing store looks for original fashion clothing sales and clearances of worldwide known designers. We participate in fashion auctions to get the lowest possible price for Top quality Clothes, Shoes and Accessories.
Buy Jeans

Khimsoo said...

// to limit the characters within a textbox
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int limit = 0;
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (textField == aTextField){
limit = 4;
}
if (textField == bTextField || textField == cTextField) {
limit = 3;
}
return !([newString length] > limit);
}

h4ns said...

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.

Arsenal vs Huddersfield Town live streaming
Arsenal vs Huddersfield Town live streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Notts County vs Manchester City Live Streaming
Notts County vs Manchester City Live Streaming
Bologna vs AS Roma Live Streaming
Bologna vs AS Roma Live Streaming
Juventus vs Udinese Live Streaming
Juventus vs Udinese Live Streaming
Napoli vs Sampdoria Live Streaming
Napoli vs Sampdoria Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
AS Monaco vs Marseille Live Streaming
AS Monaco vs Marseille Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Technology News | News Today | Live Streaming TV Channels

Chris said...

When dealing with languages such as Japanese where typing one character brings up a list of options (which may be many characters long) for auto-completion, choosing one of the auto-complete options does not seem to fire the shouldChangeCharactersInRange message, and the limit can be avoided.

In addition, if the resulting string entered is two or more characters longer than the specified limit, hitting 'backspace' will fire the message as expected but since the string is still too long to be accepted, the attempted backspace is ignored leaving the user unable to edit the textfield at all.

For these situations, I use the textFieldShouldEndEditing message (also part of the UITextFieldDelegate protocol). By making this method return NO, you can prevent the user from switching the input focus away from the textfield if the input is not valid. The drawbacks with this approach are:
1. textFieldShouldEndEditing is called after the input has already been entered into the textfield, so unless you are ok with forcefully truncating what the user entered to your desired length, you need some way to let them know they need to backspace...
2. textFieldShouldEndEditing is only called when the focus leaves the textfield, so on it's own it is still inadequate. To monitor input as it happens you still need to use either textFieldDidChange, or the method mentioned above (but check the before/after length of the string to see if the action was a backspace!)

Rich said...

Jeff, Thank you very much for the post. But I have a question about it. I'm trying to combine your advice in this post (i.e. how to limit the number of input characters), with another of your posts (i.e. "Alert View With Prompt", http://iphonedevelopment.blogspot.com/2009/02/alert-view-with-prompt.html).
I don't understand how to apply the info from this post to the "Alert View With Prompt" post. I also don't understand where "myTextField" originates. Can you please explain this to me?