3

I have a UISearchBar that behaves normally - the keyboard goes away if I hit "Search" or "Cancel".

However, when I push a new view controller on my navigation stack, if the keyboard is open, it won't close. It stays there in the old view controller, and if I navigate back to it the keyboard is still shown.

I'm stumped because my searchBarShouldEndEditing method is called as expected, and I do [activeSearchBar resignFirstResponder]. This works for "Search" or "Cancel", but not when it's triggered by the view disappearing.

My delegate code:

#pragma mark Search bar delegate methods__________________________

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)activeSearchBar
{
    NSLog(@"searchBarShouldBeginEditing");
    [activeSearchBar setShowsCancelButton:TRUE animated:YES];

    if (!showSearchType)
        return TRUE;

    if([UIView respondsToSelector:@selector(animateWithDuration:animations:)]) {
        // iOS 4.0 and later
        [UIView animateWithDuration:0.3 animations:^ {
            searchTypeView.frame = CGRectMake(0, 44, 320, 69);
            searchTypeView.bounds = CGRectMake(0, 0, 320, 69);
            grayBg.alpha = 0.6;
        }];
    } else {
        // Before iOS 4.0
        searchTypeView.frame = CGRectMake(0, 44, 320, 69);
        searchTypeView.bounds = CGRectMake(0, 0, 320, 69);
        grayBg.alpha = 0.6;
    }

    self.frame = CGRectMake(0, 0, 320, 113);

    [self bringSubviewToFront:searchTypeView];
    [self bringSubviewToFront:activeSearchBar];

    return TRUE;
}


- (BOOL)searchBarShouldEndEditing:(UISearchBar *)activeSearchBar
{
    NSLog(@"searchBarShouldEndEditing");

    if ([activeSearchBar isFirstResponder]) {
        NSLog(@"activeSearchBar isFirstResponder");
    }
    [activeSearchBar resignFirstResponder];

    [activeSearchBar setShowsCancelButton:FALSE animated:YES];

    if (!showSearchType)
        return TRUE;

    if([UIView respondsToSelector:@selector(animateWithDuration:animations:)]) {
        // iOS 4.0 and later
        [UIView animateWithDuration:0.3 animations:^ {
            searchTypeView.frame = CGRectMake(0, 9, 320, 69);
            searchTypeView.bounds = CGRectMake(0, 0, 320, 0);
            grayBg.alpha = 0;
        }];
    } else {
        // Before iOS 4.0
        searchTypeView.frame = CGRectMake(0, 9, 320, 69);
        searchTypeView.bounds = CGRectMake(0, 0, 320, 0);
        grayBg.alpha = 0;
    }

    self.frame = CGRectMake(0, 0, 320, 44);

    return TRUE;
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)activeSearchBar {
    NSLog(@"searchBarTextDidEndEditing");

    if ([activeSearchBar isFirstResponder]) {
        NSLog(@"activeSearchBar isFirstResponder");
    }

    [activeSearchBar resignFirstResponder];

}

- (void)searchBarCancelButtonClicked:(UISearchBar *)activeSearchBar
{
    NSLog(@"searchBarCancelButtonClicked");

    [activeSearchBar resignFirstResponder];
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)activeSearchBar
{
    NSLog(@"searchBarSearchButtonClicked");

    self.query = searchBar.text;

    [activeSearchBar resignFirstResponder];

    [searchView startSearch];
}

This outputs:

2011-12-07 20:00:33.061 MyApp[55725:307] searchBarShouldEndEditing
2011-12-07 20:00:33.063 MyApp[55725:307] activeSearchBar isFirstResponder
2011-12-07 20:00:33.066 MyApp[55725:307] searchBarTextDidEndEditing

Thanks for any ideas!

alex_c
  • 2,058
  • 2
  • 26
  • 34

2 Answers2

6

Also you can : declare searchBar variable in your .h file, make property etc... then on your button click event method, that pushes another view, write first line :

[yourSearchBar resignFirstResponder]; 
Maulik
  • 19,348
  • 14
  • 82
  • 137
  • This should work. It's a bit of a pain in my case because my search bar is buried a bit deep in a view hierarchy, but I don't see any reason why it wouldn't work... the main trick seems to be to resignFirstResponder *before* the view disappears. – alex_c Dec 14 '11 at 23:27
2

OK, I found a solution, although it's not great.

In the parent view controller, I put the following line BEFORE anything that would trigger a new view controller to be pushed on the navigation stack:

[self.view endEditing:YES];

This seems a bit fragile and error-prone... I would love to know if there's a better way.

alex_c
  • 2,058
  • 2
  • 26
  • 34
  • 1
    This seems a bit obvious, but did you try putting a call in viewWillDisappear to resignFirstResponder from the UISearchBar? – reddersky Dec 08 '11 at 02:47