I have a UITableView with a searchbar on the top. I used UISearchDisplayController for implementing the same. And also it has a scope bar with two buttons. In default when I launch the app, the scope bar will be displayed. When I click the cancel button after the searching, the scopebar disappeared. So is there any way to keep the scopebar even after I pressed the Cancel button. I used the following code but its not working.
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
[searchBar setShowsScopeBar:YES];
return YES;
}
Thanks :)
I've had the problem today and I think I've found a solution.
You need to do two things:
- Call 'sizeToFit' on the searchBar after setting showsScopeBar. This will ensure the searchBars frame is set correctly to include the scope bar.
- Unfortunately the table view doesn't seem to like it when the searchBar resizes and causes the scope bar to overlap the first cell. To solve this you can re-set the tableHeaderView to be the searchBar (again) which seems to fix the overlap problem.
Final code:
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
self.searchBar.showsScopeBar = YES;
[self.searchBar sizeToFit];
self.tableView.tableHeaderView = self.searchBar;
return YES;
}
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 :)
More correct way of this answer is to add logic for return result:
@property (nonatomic) BOOL shouldHideFirstResponder; //assign YES in init
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
if (self.shouldHideFirstResponder) {
self.searchBar.showsScopeBar = YES;
[self.searchBar sizeToFit];
self.table.tableHeaderView = self.searchBar;
}
return self.shouldHideFirstResponder;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
self.shouldHideFirstResponder = NO;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar {
self.shouldHideFirstResponder = YES;
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
if (!self.searchBar.text || self.searchBar.text.length < 1) {
self.shouldHideFirstResponder = YES;
}
}
来源:https://stackoverflow.com/questions/8895410/how-to-keep-scopebar-even-after-pressed-cancel-button