41

I am running into an issue where the keyboard does not get dismissed when leaving a UITextField or UITextView in a UIModalPresentationFormSheet. In addition, I've created a large button to serve as the view's background so if the user taps outside the fields it gets triggered. I am using the same code in a regular view controller, and it works as expected. In the modal view controller it does nothing. Any suggestions would be appreciated.

- (BOOL)textFieldShouldReturn:(id)sender {  
 [titleTextField resignFirstResponder];
 return YES;
}

- (BOOL)textViewShouldReturn:(id)sender {  
 [synopsisTextView resignFirstResponder];
 return YES;
}

- (IBAction)textFieldDoneEditing:(id)sender {  
 [sender resignFirstResponder];
} 

- (IBAction)textViewDoneEditing:(id)sender {  
 [sender resignFirstResponder];
} 

- (IBAction)backgroundClick:(id)sender {  
 [titleTextField resignFirstResponder];
 [synopsisTextView resignFirstResponder];
}
Chris Trahey
  • 18,202
  • 1
  • 42
  • 55
DenVog
  • 4,226
  • 3
  • 43
  • 72
  • Don't know if you solved this, but I am having a similar issue: http://stackoverflow.com/questions/3372333/ipad-keyboard-refuses-to-go-away – Kalle Aug 02 '10 at 09:50

7 Answers7

119

Overriding disablesAutomaticKeyboardDismissal to return NO as below fixed the same problem of mine. You should put this code to your view controller, from which you initiate the keyboard:

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

Also, check this SO question if you want to get a detailed explanation.

Community
  • 1
  • 1
aslı
  • 8,740
  • 10
  • 59
  • 80
  • It works, Thanks! This is so tricky. How on earth can I figure this out on my own? ughhh!! – Hlung Sep 15 '11 at 10:49
  • I think you should put the code to the view controller that is presented as modal view controller. If you are presenting modally UINavigationController (with view controllers on stack), you should subclass it and override the method there. – manicaesar Oct 06 '11 at 11:21
  • Looks like it should work, but it doesn't. I put this in both the viewController that brings up the kbd and the previous and the next, but the keyboard is still there. I'm dismissing it from the correct textField on viewWillDisappear, and it gets called.. – Maciej Swic Mar 06 '12 at 21:55
  • As was commented in the other SO question about this that @davsan linked above, try putting the disablesAutomaticKeyboardDismissal in a category on UIViewController. I had the same issue and that fixed it for me. It does give a warning, but it should be okay. – Chad Mar 30 '12 at 14:45
  • 4
    This failed for me countless times using it in my ViewController but I went ahead and added a NavigationController subclass with it and success! – Josh Kahane Aug 28 '12 at 11:19
  • 2
    If your modal view controller is in a UINavigationController, try the answer @ctrahey proposed by creating a category on UINavigationController to call disablesAutomaticKeyboardDismissal on its topViewController – joelsand Nov 19 '12 at 20:56
51

For those having trouble with UINavigationController, I think there is a better solution than a category on UIViewController. We should change the behavior of UINavigationController to ask its topViewController (in my opinion, this is how all ViewController containers should handle this).

@implementation UINavigationController (DelegateAutomaticDismissKeyboard)
- (BOOL)disablesAutomaticKeyboardDismissal {
    return [self.topViewController disablesAutomaticKeyboardDismissal];
}
kabuko
  • 36,028
  • 10
  • 80
  • 93
Chris Trahey
  • 18,202
  • 1
  • 42
  • 55
  • Nice suggestion, saved me a lot of grief! – jjxtra Jul 28 '12 at 22:28
  • 2
    should we really be overriding methods inside a category? doesn't seem right. – Edward Huynh Oct 18 '13 at 05:26
  • To help rookies like me, just subclass UINavigationController and add one method - (BOOL)disablesAutomaticKeyboardDismissal { return [self.topViewController disablesAutomaticKeyboardDismissal]; } – Joshua Dance Nov 26 '13 at 00:03
  • This should really be done as a subclass. I'm a huge fan of categories but overriding methods is the one thing they should NEVER be used for! http://stackoverflow.com/questions/5272451/overriding-methods-using-categories-in-objective-c – Rembrandt Q. Einstein Feb 04 '14 at 23:53
  • @RembrandtQ.Einstein It's a great point, but sometimes it's easy to be over-careful. The caution with Categories is when overriding a method on a class that you know has an implementation (that is, not simply one of it's ancestors). Now, it is true that doing this on *any* Apple-provided classes is inherently risky because you have no guarantees about future SDK changes. However, the value here in using a category instead of a subclass is pretty significant: You can now use this behavior even for nav controllers that you didn't control the instantiation of. A great concern, though. – Chris Trahey Feb 05 '14 at 03:53
  • @ctrahey yes it's out of an abundance of caution, but the specific danger of using a category to override a method is _specifically_ on an Apple framework class. If you want to override or extend a method on a class you don't have the source for, the correct way to do it is method swizzling. – Rembrandt Q. Einstein Feb 05 '14 at 15:36
3

If you're presenting a modal view with presentation style "form sheet", Apple apparently does not dismiss the keyboard, thinking that they don't want the keyboard to jump in and out where a user will be doing a lot of editing (i.e. "forms"). The fix would be to change presentation style or live with it.

Kalle
  • 13,186
  • 7
  • 61
  • 76
  • Yes. I'm using UIModalPresentationFormSheet. Thanks for that info. – DenVog Aug 05 '10 at 20:04
  • Annoyingly here, to get a smooth fade out from the ModalVC you need to animate out the keyboard first. http://stackoverflow.com/questions/2898353/modal-view-controller-with-keyboard-on-landscape-ipad-changes-location-when-dismi – Nick Cartwright Sep 17 '10 at 13:27
  • see @ctrahey 's answer above, adding a category to UINavigationController. Solved it for me. – Chris Ladd Nov 10 '12 at 04:45
1

If you implement the UITextFieldDelegate protocol you can inadvertently cause this behavior if you do text validation. If your validation codes returns false from textFieldShouldEndEditing when the text is invalid, the field can't relinquish it's firstResponder status and the keyboard will remain on screen in the next view.

More details at UITextField's keyboard won't dismiss. No, really

Community
  • 1
  • 1
SafeFastExpressive
  • 3,637
  • 2
  • 32
  • 39
0

The disablesAutomaticKeyboardDismissal refused to work for me on iOS 7.

But... I managed to solve this issue by simply disabling the UITextFields on the screen.

My solution is described here.

This workaround even works on Modal UIViewControllers.

Yeah... it surprised me aswell !!

Community
  • 1
  • 1
Mike Gledhill
  • 27,846
  • 7
  • 149
  • 159
0

I solved this by resizing a UIModalPresentationPageSheet. See my answer here.

Community
  • 1
  • 1
dvs
  • 12,324
  • 6
  • 38
  • 45
0

i have also facing same problem and also done everything but not thing works then i start thinking and get some result.

but this answer for those who want to dismiss keyboard on textfield click and then open pop up.

so all you need to call text field delegate

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    if textField == self.myTxtFieldName{
        self.view.endEditing(true) // keyboard hide code
        // here you can call your model or pop up code and keyboard will dismiss and your pop up open 
        return false 
    } 
     return true
} 

Sorry if this is not working for you if there is other answer then please edit it Thank you

Vipin Pareek
  • 236
  • 2
  • 10