UISearchController的使用

前言

        在iOS 8.0以上版本中,我们可以使用UISearchController来非常方便地在UITableView中添加搜索框。而在iOS8.0之前版本中,我们还是必须使用UISearchBar + UISearchDisplayController的组合方式。


1. 添加UISearchController属性

@property(strong, nonatomic) UISearchController *searchController;

@property(strong, nonatomic) NSMutableArray *allCities; // 所有城市

@property(strong, nonatomic) NSMutableArray *filteredCities; // 根据searchController搜索的城市

2. 初始化UISearchController

        使用懒加载或者在viewDidLoad中初始化UISearchController

self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];

self.searchController.searchResultsUpdater = self;

self.searchController.dimsBackgroundDuringPresentation = false;

[self.searchController.searchBar sizeToFit];

self.searchController.searchBar.backgroundColor = UIColorFromHex(0xdcdcdc);

self.tableView.tableHeaderView = self.searchController.searchBar;

3. UISearchResultsUpdating协议

        使用UISearchController要继承UISearchResultsUpdating协议,实现其中的UISearchResultsUpdating方法。

#pragma mark - searchController delegate

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {

        [self.filteredCities removeAllObjects];

        NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", self.searchController.searchBar.text];

        self.filteredCities = [[self.allCities filteredArrayUsingPredicate:searchPredicate] mutableCopy];

        dispatch_async(dispatch_get_main_queue(), ^{

                [self.tableView reloadData];

        });

}

        UISearchController的searchBar中的内容一旦发生变化,就会调用该方法。在其中,我们可以使用NSPredicate来设置搜索过滤的条件。

4. 更新UITableView数据

        引入UISearchController之后,UITableView的内容也要做相应地变动,即cell中要呈现的内容是allCities,还是filteredCities。这一点,可以通过UISearchController的active属性来判断,即判断输入框是否处于active状态。

        UITableView相关的很多方法都要根据active来做判断:

#pragma mark - tableView delegate

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

        if (!self.searchController.active) {

                return self.cityKeys.count;

        } else {

                return 1;

        }

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

        if (!self.searchController.active) {

                NSString *key = self.cityKeys[section];

                NSArray *citySection = self.cityDict[key];

                return citySection.count;

        } else {

                return self.filteredCities.count;

        }

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        static NSString *CellIdentifier = @"Cell";

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell == nil) {

                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

                cell.selectionStyle = UITableViewCellSelectionStyleNone;

        }

// 根据UISearchController的active属性来判断cell中的内容

        if (!self.searchController.active) {

                NSString *key = self.cityKeys[indexPath.section];

                cell.textLabel.text = [self.cityDict[key] objectAtIndex:indexPath.row];

        } else {

                cell.textLabel.text = self.filteredCities[indexPath.row];

        }

        return cell;

}

5. UISearchController的移除

        在viewWillDisappear中要将UISearchController移除,否则切换到下一个View中,搜索框仍然会有短暂的存在。

- (void)viewWillDisappear:(BOOL)animated {

        [super viewWillDisappear:animated];

        if (self.searchController.active) {

                self.searchController.active = NO;

                [self.searchController.searchBar removeFromSuperview];

        }

}

6. 其他属性修改

6.1 去除SearchBar默认灰色的背景颜色

        在iOS7.0之前,UISearchBar视图里直接包含UISearchBarBackground和UISearchBarTextField两个视图,在iOS7.0及之后,UISearchBar视图里包含的是一个UIView视图,UIView视图里才是 UISearchBarBackground和UISearchBarTextField两个视图。

        经多次试验,发现去除UISearchbar视图里的 UISearchBarBackground后UISearchBar的背景就透明了,代码如下:

for ( UIView *view in self.searchBar.subviews ) { 

       // for before iOS7.0

       if ( [view isKindOfClass:NSClassFromString(@"UISearchBarBackground")] ) {

               [view removeFromSuperview];

               break;

       }

       // for later iOS7.0(include)

       if ( [view isKindOfClass:NSClassFromString(@"UIView")] && view.subviews.count>0 ) {

               [[view.subviews objectAtIndex:0] removeFromSuperview];

               break;

       }

}

6.2 改变SearchController取消按钮

_searchController.searchBar.showsCancelButton = YES;

for(UIView *view in [searchController.searchBar subviews]) {

        for (UIView *subView in [view subviews]) {

                if([subView isKindOfClass:[UIButton class]]) {

                        UIButton *btn = (UIButton *)subView;

                        [btn setTitle:@"取消" forState:UIControlStateNormal];

                        [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

                }

        }

}

你可能感兴趣的:(UISearchController的使用)