16

I have a table view in a modal form sheet (iPad), and one of the cells contains a UITextField. My view controller holds a reference to the text field and is also its delegate.

When the text field hits Return, I tell it to -resignFirstResponder inside of -textFieldShouldReturn:. In another case, I want to force it to end editing, so I tell the whole table view to -endEditing:YES. Afterwards I release my local reference to the text field, and reload the row to replace it with something else.

The keyboard won't go away in either case. I don't know what's wrong, and I'm not sure how to debug further. I've never had a sticky keyboard problem with any other text editing I've done-- the firstResponder resignation has always behaved as expected.

Any thoughts? Thanks.

Ben Zotto
  • 70,108
  • 23
  • 141
  • 204
  • Is your code run? Do you call resignFirstResponder on the correct textfield? – Eiko Dec 04 '11 at 22:55
  • Yeah. I ensured that `isFirstResponder` is YES on the textField I call `-resignFirstResponder` on immediately before I call it. – Ben Zotto Dec 04 '11 at 22:59

6 Answers6

22

The Apple docs describe this exception:

On the iPad, if a view controller modally presents its view using the "form sheet" style, the keyboard, once shown, is not hidden until the user taps the dismiss key or the modal view controller is programmatically dismissed. The purpose of this behavior is to avoid excessive animations as a user moves between views that are largely, but not entirely, text fields.

Which happens to apply here (modal form sheet on iPad). It's apparently just not possible to dismiss the keyboard in this case. Super. :\

Ben Zotto
  • 70,108
  • 23
  • 141
  • 204
  • 1
    +1: i just found this answer after pulling out my hair for an hour trying to figure this out. and the answer is apple did this idiotic implementation ON PURPOSE? you've gotta be joking Apple. – Jesse Naugher Jan 04 '12 at 15:54
  • 11
    You can override the `disablesAutomaticKeyboardDismissal` method and return NO for the view controller that is being presented modally. This will work around the default behavior of preventing the keyboard from being dismissed. – gdavis Apr 02 '12 at 19:54
  • 1
    Unfortunately, the disablesAutomaticKeyboardDismissal fix seems to have stopped working with iOS 6. Anyone else seeing the same? – Snips Sep 27 '12 at 22:27
  • oh crap. Can't believe this is done un purpose by Apple. Isn't that painful? – DZenBot Dec 19 '12 at 15:07
  • 1
    @Snips It still works in iOS 6.『if you present your view controller inside a UINavigationController, you must subclass UINavigationController and override the method there.』 see: http://stackoverflow.com/questions/3316700/dismiss-keyboard-on-ipad/14879832#14879832 – Hvordan har du det May 07 '13 at 15:52
11

Implement -disablesAutomaticKeyboardDismissal and return NO. It does work on iOS 6, but you have to implement it in the right controller. If you have a modal form sheet navigation controller with a child controller that has text fields, it's the navigation controller that needs the method implementation, not the child.

(See also Dismiss keyboard on IPAD)

Community
  • 1
  • 1
Rhult
  • 1,646
  • 15
  • 10
  • Oh yes! Finally solved this for me. Remember to set this in the view controller presenting the view controller containing the text field. – Daniel Nordh May 19 '14 at 14:37
1

Since the disablesAutomaticKeyboardDismissal override isn't working on iOS6, I had to connect each text field's "Did End On Exit" event to a method and then dismiss the keyboard there, like so:

- (IBAction)doneEditing:(id)sender {

[sender endEditing:YES];

}

sounder_michael
  • 576
  • 6
  • 17
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 even works on Modal UIViewControllers.

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

I just found a unique situation where this occurs. I have a view that when dismissed leaves the keyboard up on the screen. I checked everything, my UITextFields delegates were connected to my view, etc. Trying to dismiss the keyboard manually in viewWillDisappear() wouldn't work, either by resignFirstResponder() on the fields or endEditing() on the view.

Then I realized it was my field validation code in the delegate methods themselves. Every time editing ended in a field I validate the text in textFieldShouldEndEditing delegate method to ensure the text is reasonable, much like this, and don't allow them to tab out of the field until it is validated.

  func textFieldShouldEndEditing(textField: UITextField) -> Bool
    {
        if self.validateField(textField) {
           return true
        } else {
          return false
        }
   }

So when a user returned to the previous view without entering any text, the validation fails, the text field is not allowed to relinquish it's first responder status, and the keyboard remains on screen as they return to the previous view.

It's a unusual situation but hopefully this will help someone else who runs into it.

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

In swift just give your UITextField a delegate and generate textFieldShouldReturn(), see below for example -

class ViewController: UIViewController, UITextFieldDelegate {
    func settingUpTextField() {
        textField.delegate = self;
        return;
    }
    ...
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder();
        return true;
    }
}

done!

J-Dizzle
  • 4,861
  • 4
  • 40
  • 50