iphone - How to dismiss keyboard for UITextView with return key?

ID : 6733

viewed : 234

Tags : iphoneobjective-ckeyboarduitextviewiphone-softkeyboardiphone





Top 5 Answer for iphone - How to dismiss keyboard for UITextView with return key?

vote vote

95

Figured I would post the snippet right here instead:

Make sure you declare support for the UITextViewDelegate protocol.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {      if([text isEqualToString:@"\n"]) {         [textView resignFirstResponder];         return NO;     }      return YES; } 

Swift 4.0 update:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {     if text == "\n" {         textView.resignFirstResponder()         return false     }     return true } 
vote vote

85

UITextView does not have any methods which will be called when the user hits the return key. If you want the user to be able to add only one line of text, use a UITextField. Hitting the return and hiding the keyboard for a UITextView does not follow the interface guidelines.

Even then if you want to do this, implement the textView:shouldChangeTextInRange:replacementText: method of UITextViewDelegate and in that check if the replacement text is \n, hide the keyboard.

There might be other ways but I am not aware of any.

vote vote

72

I know this has been answered already but I don't really like using the string literal for the newline so here is what I did.

- (BOOL)textView:(UITextView *)txtView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {     if( [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location == NSNotFound ) {         return YES;     }      [txtView resignFirstResponder];     return NO; } 

Swift 4.0 update:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if (text as NSString).rangeOfCharacter(from: CharacterSet.newlines).location == NSNotFound {     return true } txtView.resignFirstResponder() return false } 
vote vote

64

I know this has been answered a lot of times, but here are my two cents to the issue.

I found the answers by samvermette and ribeto really useful, and also the comment by maxpower in the ribeto's answer. But there is a problem with those approaches. The problem that matt mentions in the samvermette's answer and it's that if the user wants to paste something with a line break inside it, the keyboard would hide without pasting anything.

So my approach is a mixture of the three above mentioned solutions and only checking if the string entered is a new line when the length of the string is 1 so we make sure the user is typing instead of pasting.

Here is what I have done:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {     NSRange resultRange = [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch];     if ([text length] == 1 && resultRange.location != NSNotFound) {         [textView resignFirstResponder];         return NO;     }      return YES; } 
vote vote

54

A more elegant way is to dismiss the keyboard when the user taps somewhere outside of the keyboard's frame.

First, set your ViewController's view to the class "UIControl" in the identity inspector in UIBuilder. Control-drag the view into the ViewController's header file and link it as an action with the event as Touch Up Inside, such as:

ViewController.h

-(IBAction)dismissKeyboardOnTap:(id)sender; 

In the main ViewController file, ViewController.m:

-(IBAction)dismissKeyboardOnTap:(id)sender     {          [[self view] endEditing:YES];     } 

You can require a double tap or long touch using similar techniques. You may need to set your ViewController to be a UITextViewDelegate and connect the TextView to the ViewController. This method works for both UITextView and UITextField.

Source: Big Nerd Ranch

EDIT: I'd also like to add that if you are using a UIScrollView, the above technique may not work as easily through the Interface Builder. In that case, you could use a UIGestureRecognizer and call the [[self view] endEditing:YES] method within it instead. An example would be:

-(void)ViewDidLoad{     ....     UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc]          initWithTarget:self action:@selector(tap:)];     [self.view addGestureRecognizer: tapRec];     .... }  -(void)tap:(UITapGestureRecognizer *)tapRec{     [[self view] endEditing: YES]; } 

When the user taps outside of the keyboard and does not tap an entry space, the keyboard will dismiss.

Top 3 video Explaining iphone - How to dismiss keyboard for UITextView with return key?







Related QUESTION?