ios UITableView 搜索

自己实现 UITableView 搜索,相对于使用 UISearchDisplayController 来说自己写稍微麻烦了那么一点点,但是更加灵活。主要就是用一个字段区分出当前是搜索还是非搜索,然后 reload 相应的 data 就行了,和 UISearchDisplayController 的实现也很像,不过 UISearchDisplayController是两个 tableview 切换,这里我们是一个 tableview load 不同的数据。

关键代码:

@interface MainTableViewController : UIViewController<UISearchBarDelegate,UITableViewDelegate,UITableViewDataSource>{
    UITableView *mytableView;
    NSArray *data;
    NSMutableArray *filterData;
    BOOL isFiltered; // 标识是否正在搜素
    UIView *mask;
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    mytableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height-20)];
    mytableView.dataSource = self;
    mytableView.delegate = self;
    [self.view addSubview:mytableView];
    
    UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width
                                                                           , 44)];
    searchBar.placeholder = @"搜索";
    searchBar.delegate = self;
    mytableView.tableHeaderView = searchBar;
    
    // 添加一层 mask
    mask = [[UIView alloc] initWithFrame:CGRectMake(0, 20 + 44, self.view.frame.size.width, self.view.frame.size.height -20 -44)];
    [self.view addSubview:mask];
    mask.backgroundColor = [UIColor blackColor];
    mask.alpha = 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // 通过 isFiltered 区分出当前显示的是搜索结果集还是原结果集
    if (isFiltered) {
        return filterData.count;
    }
    
    return data.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellid = @"cellid";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellid];
    
    if (cell==nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellid];
    }
    
    // 通过 isFiltered 区分出当前显示的是搜索结果集还是原结果集
    if (isFiltered) {
        cell.textLabel.text = filterData[indexPath.row];
    }else{
        cell.textLabel.text = data[indexPath.row];
    }
    
    return cell;
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
    // 开始搜索时弹出 mask 并禁止 tableview 点击
    NSLog(@"searchBarTextDidBeginEditing");
    isFiltered = YES;
    searchBar.showsCancelButton = YES;
    mask.alpha = 0.3;
    mytableView.allowsSelection = NO;
    mytableView.scrollEnabled = NO;
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
    NSLog(@"searchBarTextDidEndEditing");
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
    NSLog(@"textDidChange");
    if (searchText.length == 0) {
        isFiltered = NO;
        mask.alpha = 0.3;
        mytableView.allowsSelection = NO;
        mytableView.scrollEnabled = NO;
        [mytableView reloadData];
        return;
    }
    
    isFiltered = YES;
    mask.alpha = 0;
    mytableView.allowsSelection = YES;
    mytableView.scrollEnabled = YES;
    
    // 谓词搜索
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self contains [cd] %@",searchText];
    filterData =  [[NSMutableArray alloc] initWithArray:[data filteredArrayUsingPredicate:predicate]];
    [mytableView reloadData];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *) sb{
    // 点击 cancel 时去掉 mask ,reloadData
    sb.text = @"";
    [sb setShowsCancelButton:NO animated:YES];
    mytableView.allowsSelection = YES;
    mytableView.scrollEnabled = YES;
    [sb resignFirstResponder];
    mask.alpha = 0;
    
    isFiltered = NO;
    [mytableView reloadData];
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString *text;
    
    if (isFiltered) {
        text = filterData[indexPath.row];
    }else{
        text = data[indexPath.row];
    }
    
    NSLog(@"you click index:%d  %@",indexPath.row,text);
}

基于 ios7.1 布局写了一个 demo: http://pan.baidu.com/s/1ntn0MeP

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。