I have also been battling with these kinds of UISearchBarController
problems the last few days myself, and I have to say the best way to do anything unusual with a UISearchBar is to not use a UISearchDisplayController
at all!
Just use a UISearchBar
and the UISearchBarDelegate
methods and roll your own, then you can set everything all up to act exactly how you want.
Here what I did in one recent project.
- The scope bar always stays visible
- I filter immediately as text is entered
- I filter immediately if scope is changes
- I hide the cancel button when it's not needed
- I hide the keyboard when it's not needed
// Filters the table when requested
- (void)filterContentForSearchBar:(UISearchBar *)searchBar
{
NSString *scope = [[searchBar scopeButtonTitles] objectAtIndex:[searchBar selectedScopeButtonIndex]];
NSString *search = [searchBar text];
NSMutableArray *predicates = [[NSMutableArray alloc] init];
if ([scope isEqualToString:@"Selected"])
{
[predicates addObject:[NSPredicate predicateWithFormat:@"selected == 1"]];
}
if (search && search.length) {
[predicates addObject:[NSPredicate predicateWithFormat:@"name contains[cd] %@", search]];
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
self.filteredObjectList = [self.objectList filteredArrayUsingPredicate:predicate];
[self.myTableView reloadData];
}
#pragma mark - UISearchBarDelegate Methods
// React to any delegate method we are interested in and change whatever needs changing
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = true;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = false;
[searchBar resignFirstResponder];
searchBar.text = nil;
[self filterContentForSearchBar:searchBar];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = false;
[searchBar resignFirstResponder];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self filterContentForSearchBar:searchBar];
}
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
{
[self filterContentForSearchBar:searchBar];
}
Works great :)