質問

In our app, there's a situation where the user enters something in a textbox and then presses the back button to go back to the master screen.

If we run that on iOS 7, the keyboard does not disappear, it just stays there. The user can still navigate through the app, but all text fields are disabled, meaning you can't enter text anywhere. The only option the user has is killing the app and starting fresh.

We tried to add resignFirstResponder messages, but that didn't help anything.

There's much code involved, and we're actively working on the issue. Meantime, has anyone experienced that problem too, and maybe found a way to make it go away?

役に立ちましたか?

解決

I had the same issue like you when I compiled the app for iOS 7 and I did the following changes:

  1. Make sure you add [textfield resignFirstResponder] before dismissing the viewController for example:

    [_passwordInput resignFirstResponder];
    [_emailInput resignFirstResponder];
    [self performSegueWithIdentifier:@"forgotPassword" sender:self];
    
  2. Just to be sure the keyboard disappears add [textfield resignFirstResponder] in viewWillDisappear for example :

    - (void) viewWillDisappear:(BOOL)animated
    {
       [_passwordInput resignFirstResponder];
       [_emailInput resignFirstResponder];
    }
    
  3. If your viewController is presented using UIModalPresentationFormSheet add this to your viewController just to make sure the textfields will respond resignFirstResponder:

    - (BOOL)disablesAutomaticKeyboardDismissal
    {
       return NO;
    }
    

In your case, override the back button action or just use viewWillDisappear to check when the user pressed the back button and then call resignFirstResponder before [super viewWillDisappear] something like this:

-(void) viewWillDisappear:(BOOL)animated 
{
   [_passwordInput resignFirstResponder];
   [_emailInput resignFirstResponder];
   [super viewWillDisappear:animated];
}

他のヒント

Try [self.view resignFirstResponder], instead of [textfield resignFirstResponder] on viewWillDisappear.

[textfield resignFirstResponder] should do the job, but to make sure and for not to loop through all your textFields you can use:

[self.view endEditing:YES];

From the doc:

use to make the view or any subview that is the first responder resign (optionally force).

in general I find this useful

[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];

you can add this in viewWillDisappear: or viewDidDisappear:

this will hide the keyboard without a reference to the currently focused text field

I had the same problem only with MoreViewController in UITabBarController (iOS 8.3). Maybe this solution not very 'nice' and little complicated, but seems like it works, hope it will help you too.

@interface ViewController ()

@property (nonatomic) BOOL needToHideKeyboard;
@property (nonatomic, strong) IBOutlet UITextField *txtField;
@property (nonatomic, strong) IBOutlet UIScrollView *scrollView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    self.needToHideKeyboard = NO;
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    [self hideKeayboard];
}

- (void)hideKeayboard
{
    if (self.needToHideKeyboard) {
        [self.txtField resignFirstResponder];
    }
}

- (void)keyboardWasShown:(NSNotification *)notification
{
    self.needToHideKeyboard = YES;

    NSDictionary *info = [notification userInfo];
    CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    // Shift scroll view content insets on the keyboard height
    UIEdgeInsets contentInsets = self.scrollView.contentInset;
    contentInsets.bottom = keyboardSize.height;
    self.scrollView.contentInset = contentInsets;
}

- (void)keyboardWillBeHidden:(NSNotification *)notification
{
    self.needToHideKeyboard = NO;

    // Reset keyboard content insets
    UIEdgeInsets contentInsets = self.scrollView.contentInset;
    contentInsets.bottom = [self.bottomLayoutGuide length];
    self.scrollView.contentInset = contentInsets;
}

@end

If your view controller implements textFieldDidEndEditing, make sure you don't set another view to be the first responder if the view is disappearing. textFieldDidEndEditing will get invoked when you call resignFirstResponder, or [self.view endEditing:YES].

[self.view endEditing:YES];

stopped working on my device iOS9.x

We can also do this in the viewWillDisappear method

for (UIView *subview in self.view.subviews) {
        if ([subview canPerformAction:@selector(endEditing:) withSender:nil]) {
            [subview endEditing:YES];
        }
        if ([subview canResignFirstResponder]) {
            [subview resignFirstResponder];
        }
    }

This will loop through the responders and resign the responder status.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top