搜索功能,基本每个app标配。
实现起来很简单,但是iOS8后苹果建议使用UISearchController,官方Demo:Table Search with UISearchController
实际开发基本也都还是用的老的UISearchDisplayController+UISearchBar的方案,因为要照顾一些版本低的用户。
发现时间长没写都忘记差不多了,闲暇之余,一起整理下,方便以后翻阅。
这篇先从UISearchDisplayController开始。比较简单,就不罗嗦了,直接贴代码。
- UITableView步骤略去。
-
新建一个UISearchBar
1 _searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)]; 2 _searchBar.delegate = self; 3 _searchBar.placeholder = @"搜索"; 4 _searchBar.backgroundColor = [UIColor clearColor];
-
根据searchBar新建一个UISearchDisplayController
1 _searchDisplayCtl = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self]; 2 _searchDisplayCtl.delegate = self; 3 _searchDisplayCtl.searchResultsDataSource = self; 4 _searchDisplayCtl.searchResultsDelegate = self;
-
设置tableView的tableHearderView为searchBar
1 _tableView.tableHeaderView = _searchBar;
-
更改searchBar的Cancel按钮为“取消”,注意:因为iOS7后和之前的层次结构不同,iOS7前遍历一次即可拿到,iOS7后需要遍历两次,在UISearchBar的代理方法中设置
1 //change searchBar's Cancel button to “取消”,注意:因为iOS7后和之前的层次结构不同,iOS7前遍历一次即可拿到,iOS7后需要遍历两次 2 - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar 3 { 4 //要先让cancelBtn显示,否则设置不了title 5 searchBar.showsCancelButton = YES; 6 7 //设置title为“取消” 8 for (id sView in searchBar.subviews) 9 { 10 if ([sView isKindOfClass:[UIButton class]]) 11 { 12 [(UIButton *)sView setTitle:@"取消" forState:UIControlStateNormal]; 13 break; 14 } 15 for (id ssView in [sView subviews]) 16 { 17 if ([ssView isKindOfClass:[UIButton class]]) 18 { 19 [(UIButton *)ssView setTitle:@"取消" forState:UIControlStateNormal]; 20 } 21 } 22 } 23 }
- 最后一步,搜索展示结果。UISearchDisplayController代理中处理
1 #pragma mark - UISearchDisplayController 2 - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString 3 { 4 [_resultList removeAllObjects]; 5 6 for (NSString *subString in _dataList) 7 { 8 if ([subString rangeOfString:searchString].location != NSNotFound) 9 { 10 [_resultList addObject:subString]; 11 } 12 } 13 14 return YES; 15 }
最简便的一个搜索完成了,UISearchBar和UISearchDisplayController还提供给我们很多其他的代理方法,都是些常规读名取意型的,就不一一介绍了,实际用到了看下就可以了。苹果封装的已经很好,而且UI也蛮漂亮的,所以我们也没必要自己写一个。
不过,实际过程中有两点可能会用到。网上也挺多资料,大概整理下。方便以后查找使用。
- 更改UISearchBar的背景
项目中可能会有需要我们改变其背景颜色或者背景图片的需求,其大概实现原理类似更改cancel按钮的title。需要注意的还是iOS版本不同,searchBar的层次结构不同
- 先设置searchBar的背景透明
_searchBar.backgroundColor = [UIColor clearColor];
2. 移除掉searchBar的UISearchBarBackground,可以打印看下searchBar的层次结构。这里有篇整理好的文章,想了解的也可以看下: UISearchBar在iOS不同版本下的层次结构
> 采用了类别的方式来添加方法。代码:
[_searchBar removeShadow];
> UISearchBar类别中添加方法。代码:
1 - (void)removeShadow 2 { 3 4 UIView *sView = [self findViewWithClassName:@"UISearchBarBackground"]; 5 [sView removeFromSuperview]; 6 7 // 低于7.0版本的需要重新设置下搜索textField边框属性 8 if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0) 9 { 10 for( UIView *subview in self.subviews ) 11 { 12 if ([subview isKindOfClass:[UITextField class]]) 13 { 14 UITextField *textField = (UITextField *)subview; 15 textField.borderStyle = UITextBorderStyleNone; 16 textField.layer.borderWidth = 1.f; 17 textField.layer.borderColor = [UIColor clearColor].CGColor; 18 textField.layer.cornerRadius = 14.0f; 19 textField.background = nil; 20 textField.backgroundColor = [UIColor whiteColor]; 21 break; 22 } 23 } 24 } 25 26 }
> UIView类别中添加方法,代码:
1 - (UIView *)findViewWithClassName:(NSString *)className 2 { 3 return [self findViewWithClass:NSClassFromString(className)]; 4 } 5 6 - (UIView *)findViewWithClass:(Class)class 7 { 8 if ([self isKindOfClass:class]) { 9 return self; 10 } 11 12 for (UIView *subView in self.subviews) 13 { 14 // 这里采用递归是因为iOS7以后需要遍历两次才能拿到 15 UIView *retView = [subView findViewWithClass:class]; 16 17 if (retView) 18 { 19 return retView; 20 } 21 } 22 23 return nil; 24 }
3. 移除掉后,我们可以自定义一个UIView加上背景颜色或者UIImageView添加背景图片,然后将其插入searchBar中。当然也可以不移除的情况下直接插入,只不过插入的下标不同。注意区分
1 UIView *cusView = [[UIView alloc] initWithFrame:_searchBar.bounds]; 2 cusView.backgroundColor = [UIColor orangeColor]; 3 // 这里如果前面移除了,index = 0 ,没有移除index = 1 4 [_searchBar insertSubview:cusView atIndex:0];
- 关于ScopeBar
ScopeBar,先贴两张图,相信大家一看就知道是什么了。
知道是什么,就够了,实际真的用到了,帮大家找了个资料,比较详尽: ScopeBar的使用 我就不啰嗦了