17

I have a UISearchBar which when clicked, shows the keyboard. However if the user presses the home button while the keyboard is shown and then goes back into the app, the keyboard is still visible. How can I hide th keyboard when the app closes/enters background?

I've tried the following in viewDidDisappear:

[eventSearchBar resignFirstResponder];

[eventSearchBar endEditing:YES];

I've also tried this in the delegate in appDidEnterBackground:

[self.rootController.navigationController.view endEditing:YES];

None of these worked.

Dave
  • 783
  • 3
  • 15
  • 25
  • Have you tried it in willEnterBackground? – Robot Woods Aug 18 '12 at 12:42
  • I don't think there is a willEnterBackground method – Dave Aug 18 '12 at 12:45
  • 1
    There is a `applicationWillResignActive:` method. Read this: http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html – Adam Aug 18 '12 at 12:55
  • thanks, I tried resignFirstResponder and endEditing in this method but still no luck, is rootController.navigationController.view the correct way to be calling it? – Dave Aug 18 '12 at 13:06
  • by the way rootController is of type TabBarController – Dave Aug 18 '12 at 13:06
  • Did you try `searchDisplayController.active = NO;` ? – Martin R Aug 18 '12 at 13:25

6 Answers6

43

you can do this in appDelegate....

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self.window endEditing:YES];
}
Rajneesh071
  • 30,846
  • 15
  • 61
  • 74
  • 2
    `viewWillDisappear` is not called when the app goes into background. – Martin R Aug 18 '12 at 14:29
  • That is probably a matter of taste. I prefer to do this locally in the view controller that it applies to. – Martin R Aug 18 '12 at 14:49
  • 1
    This is the only solution of your problem....because neither viewwillapper nor viewwilldisapper called when app is minimize...it you want to do this then you have to do this in applicationDidEnterBackground method.. – Rajneesh071 Aug 18 '12 at 14:58
  • 1
    or you have to access your view in applicationDidEnterBackground...and then you can do [self.view endEditing:YES];... – Rajneesh071 Aug 18 '12 at 14:59
  • There is another solution (see my answer). – Martin R Aug 18 '12 at 14:59
  • if you can do this in one line then why to write huge of code...? – Rajneesh071 Aug 18 '12 at 15:03
  • As I said, it is a matter of taste. You might have several loaded view controllers and each of them has to perform some cleanup when the app goes into background (stop editing, stop downloading etc.). - But we don't have to argue. We both presented a solution and that's fine. - And I will not respond by downvoting your answer. – Martin R Aug 18 '12 at 15:10
  • 1
    PUT THIS METHOD IN YOUR APPDELEGATE.M – Gajendra K Chauhan Feb 26 '14 at 05:01
  • It can be put in applicationWillResignActive. – Swaroop S Jul 13 '15 at 09:21
7

Swift version of this:

func applicationDidEnterBackground(application: UIApplication) {
    window?.endEditing(true)
}
Esqarrouth
  • 38,543
  • 21
  • 161
  • 168
4

In your view controller, for example in the init method, register for the UIApplicationWillResignActiveNotification:

[[NSNotificationCenter defaultCenter] addObserver:self 
    selector:@selector(willResignActive:)
    name:UIApplicationWillResignActiveNotification
    object:nil];

When the app goes into background, make the search display controller inactive. This removes the focus from the search field and hides the keyboard:

- (void)willResignActive:(NSNotification *)note
{
    self.searchDisplayController.active = NO;

    // Alternatively, if you only want to hide the keyboard:
    // [self.searchDisplayController.searchBar resignFirstResponder];
}

And don't forget to remove the observer in the dealloc method:

[[NSNotificationCenter defaultCenter] removeObserver:self
    name:UIApplicationWillResignActiveNotification
    object:nil];
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
1

Solution in swift 3.2 Version

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(hideTextField), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    func hideTextField(){
        eventSearchBar.endEditing(true)
    }
Sudhi 9135
  • 745
  • 8
  • 17
1

The best way is to put window?.endEditing(true) in applicationWillResignActive on AppDelegate:

func applicationWillResignActive(_ application: UIApplication) {
    window?.endEditing(true)
}
Fabio
  • 5,432
  • 4
  • 22
  • 24
0

I've had all standard methods fail on my sporadically. So far this is the only way I've gotten solid results.

In topmost controller.

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignActiveNotification:) name:UIApplicationWillResignActiveNotification object:nil];
}

-(void) willResignActiveNotification:(NSNotification*) vNotification {
    [[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
    [self setEditing:NO];
}

There is an odd case where a text field will no longer respond to resignFirstResponder or endEditing but still has keyboard up.

Andres Canella
  • 3,706
  • 1
  • 35
  • 47