How to keep scopebar even after pressed Cancel button?

蹲街弑〆低调 提交于 2019-12-17 20:26:38

问题


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 :)


回答1:


I've had the problem today and I think I've found a solution.

You need to do two things:

  1. Call 'sizeToFit' on the searchBar after setting showsScopeBar. This will ensure the searchBars frame is set correctly to include the scope bar.
  2. 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;
}



回答2:


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 :)




回答3:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!