In a previous post I presented a framework for creating a data entry screen. That code focused mainly on UITextFields and allowed the user to move to the next field by tapping the Return key on the keyboard.
What if you have one or more UITextViews on your data entry screen because you want the user to be able to enter multiple lines of text? Well the UITextView handles the Return key internally and adds a new line to the text being entered, just like you would expect when you’re writing text in a text editor. And there is no equivalent of textFieldShouldReturn for UITextView.
If you don’t care about newlines in the entered text and you just want to exit the field when the Return key is tapped, then add the following method to the UITextViewDelegate:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { BOOL shouldChangeText = YES; if ([text isEqualToString:@"\n"]) { // Find the next entry field BOOL isLastField = YES; for (UIView *view in [self entryFields]) { if (view.tag == (textView.tag + 1)) { [view becomeFirstResponder]; isLastField = NO; break; } } if (isLastField) { [textView resignFirstResponder]; } shouldChangeText = NO; } return shouldChangeText; }
The shouldChangeTextInRange method is called after each keystroke is received by the UITextView, but before it’s shown on screen. If the text is a “\n” character (the Return key) then we either set first responder to the next field, or hide the keyboard in the case that this is the last field. (The entryFields method is explained in the previous post.) Return NO if a return character was detected since we don’t want the new line to show up in the UITextView, otherwise return YES and the text will be processed and shown in the UITextView as normal.
April 5th, 2010 at 09:43
Thank you, very helpful!
January 16th, 2012 at 07:49
Thank you, that’s help me a lot !
May 23rd, 2012 at 09:57
Hi, great little piece, really helpful; though I think this would be a bit more portable as it covers all newline variants. You can easily ass the next responder code in to the else.
-(BOOL) textView:(TableTextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if( [text isEqualToString:[text stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]]] ) {
return YES;
} else {
[textView resignFirstResponder];
}
}
January 24th, 2014 at 16:47
I like this method and use it extensively, but how can a user exit the text field w/out entering data? The return key on the default keyboard is default disabled if there is no text…
January 24th, 2014 at 17:30
Ha ha, never mind! After a few days of struggle the answer came to me minutes later. UITextView responds to enablesReturnKeyAutomatically BUT (a) the default value |NO| seems to be ignored in some cases AND (b) setting to |NO| enables the return key, while setting to |YES| disables it… very counter-intuitive!
January 2nd, 2018 at 05:42
for swift version i may introduce the following
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == text.trimmingCharacters(in: .newlines) {
return true;
}else{
textView.resignFirstResponder()
return false
}
}