参考资料
ios7自定义UISearchBar注意的问题:(http://www.tuicool.com/articles/VNzUzy3)
ios9使用中的问题及解决
在ios8中已经将”UISearchDisplayController”注销了,因为这个类职能将结果显示雨”tableView”上,从ios8开始取而代之的是”UISearchController”类。”UISearchController”类可以将结果显示于”collectionView”或是”mapVIew”上,功能先进,易控制。
自定义UISearch Bar
UISearch Bar 视图层次结构
控制台法
自定义”UISearchbar”最困难的就是设置背景图片了,必须了解它的视图层次结构,参考资料中使用控制台输入”po [self.searchBar recursiveDescription]” 命令来获取层次。
View UI Hierarchy 模式
在模拟器上运行APP,然后切换到”Show the Debug navigator”,快捷键”Command+6”,找到”View UI Hierarchy”模式,当前页面的层次结构就显示出来了。
示例代码
可以看出”UISearchBar”的样式是封装在它的下层”UIView”中的,其中包括”UISearchBarBackground(UIImage)”和”UISearchBarTextField”,所以只是设置”setBackgroundImage”或者”setBackgroundColor”的效果都不是很好,原因就是”UIView”中有两个UI控件,所以选用”setBarTintColor”,可以解决此问题。代码如下:
@interface ViewController: UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchResultsUpdating> {
NSArray *searchResult;
UISearchController *mySearchController;
}
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end
//Init UISearchController
mySearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
mySearchController.searchResultsUpdater = self;
mySearchController.searchBar.delegate = self;
mySearchController.dimsBackgroundDuringPresentation = NO;
mySearchController.hidesNavigationBarDuringPresentation = NO;
[mySearchController.searchBar setBarTintColor:UIColorFromRGB(0x5687a5)];
[mySearchController.searchBar setTintColor:UIColorFromRGB(0xb39191)];
[mySearchController.searchBar setFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44)];
[self.view addSubview:mySearchController.searchBar];
mySearchController.definesPresentationContext = YES;
UISearchController
显示搜索结果
初始化”UISearchController”之后还需要实现”UISearchResultsUpdating”协议中的”updateSearchResultsForSearchController:”方法,代码如下:
if (searchController.isActive) { NSString *searchString = searchController.searchBar.text; if ([searchString length] > 0) { NSPredicate *p = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchString]; searchResult = [list filteredArrayUsingPredicate:p]; } else { searchResult = nil; } } else { searchResult = nil; } [self.tableView reloadData];
由于是在”UITableView”上显示搜索结果,那么有关”UITableViewDelegate”的方法,实现的时候要判断”if (searchResults != nil)”,来区分是现实搜索结果的”cell”还是显示原来的”cell”。
取消焦点
还有一个容易忽略的问题就是当我们点击搜索结果时,页面需要跳转,如果”UISearchBar”的焦点没有取消,则它不会消失,在下个页面中还会留在当前位置。所以使用”StoryBoard”设置”Segue Action”跳转的需要实现”prepareForSegue:”代理方法,此方法会在执行”Segue”之前调用,代码如下:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { //Set Search Controller Active Property [mySearchController setActive:NO]; }
如果是使用代码进行跳转的,在跳转前加入”[mySearchController setActive:NO];”即可,代码示例:添加在”tableView: didSelectRowAtIndexPath:”方法中:
//Set Search Controller Active Property [mySearchController setActive:NO]; //Load The Next View UITableViewController *view = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewIdentifier"]; [self.navigationController showViewController:view sender:nil];
持续更新