6
votes

I'm debugging my code, where UISearchBar's delegate method searchBarTextDidBeginEditing: is called exactly twice every time I tap on the search bar (which is in the navigation bar).

The odd thing is that only this delegate method is called twice. The others are called only once within the whole proccess, which is the correct behavior.

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
    // called only once
    return YES;
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    // called twice every time
    [searchBar setShowsCancelButton:YES animated:YES];
}

- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
    // called only once
    [searchBar setShowsCancelButton:NO animated:YES];    
    return YES;
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    // called only once        
}

Any idea what could be wrong?

The UISeachrBar is set up in Storyboard, with properly connected outlets, although it's not added to any view, and in the particular view controller's viewDidLoad is the following line that adds the search bar to the navigation bar:

self.searchDisplayController.displaysSearchBarInNavigationBar = YES;

I'm using Xcode 5.0.1 and running the code in iOS 7.0.3 Simulator.

4
Is it possible you have two search bars on top of each other ?GuybrushThreepwood
I'm experiencing this as well, and it just seems like a iOS bug. I created a blank project with a UITableView and a UISearchDisplayController, showing the UISearchBar in the navigationBar. The following delegate methods are called twice: -searchBarTextDidBeginEditing: -searchBar:textDidChange: -searchBarCancelButtonClicked:Bart Vandendriessche
Yes, this is weird. I have the same issue but I am too greedy to start a bounty with my rating)))fnc12
I have this issue too on Xcode 8.2.1 :DMohyG

4 Answers

2
votes

I was experiencing the same issue, and dug in a bit deeper.

In my case, I had a subclass of UISearchDisplayController which functioned as UISearchDisplayDelegate for itself, and UISearchBarDelegate for its UISearchBar.

As it turns out, the problem is that UISearchDisplayController implements the following methods that collide with theUISearchBarDelegate` protocol:

- (void)searchBar:(id)arg1 textDidChange:(id)arg2;
- (void)searchBarCancelButtonClicked:(id)arg1;
- (void)searchBarResultsListButtonClicked:(id)arg1;
- (void)searchBarSearchButtonClicked:(id)arg1;
- (void)searchBarTextDidBeginEditing:(id)arg1;

This means if you make a UISearchDisplayController the delegate of its own UISearchBar, those methods will be called twice.

0
votes

I found that if you unset the searchBar delegate and only keep the searchDisplayController delegate the method is not called at all any more. So the only workaround i could come up with is putting this in the beginning of your searchBarTextDidBeginEditing and searchBarTextDidEndEditing.

static NSDate *lastInvocation;

if ([[NSDate date] timeIntervalSinceDate:lastInvocation] < 0.1f) {
    lastInvocation = [NSDate date];
    return;
} else {
    lastInvocation = [NSDate date];
}
0
votes

I found this solution: [searchBar setShowsCancelButton:NO animated:YES]; [searchBar resignFirstResponder]; But funny thing is, I removed it after some two rounds of testing, the code is just called once, not twice

0
votes

I had problem with searchBarSearchButtonClicked: method been called twice. Problem was solved by calling [searchBar resignFirstResponder];

    #pragma mark - UISearchViewDelegate methods
    - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
     // Do things
     [searchBar resignFirstResponder];
    }