IOS中UISearchController搜尋框篩選功能實現
在之前的部落格中,我曾寫過一個搜尋框功能的一個實現!有時候,我們需要利用搜索框進行對資料的一個篩選,比如qq的聯絡人功能上面的搜尋篩選功能的實現!
廢話不多說,先直接上程式碼
首先我們建立一個繼承uitableview的控制器searchTableViewController,然後在AppDelegate中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self .window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
self.window.rootViewController=[[searchTableViewController alloc]initWithStyle:UITableViewStyleGrouped];
return YES;
}
searchTableViewController.h檔案中,我們需要用到一個搜尋控制器UISearchController,並且實現一個UISearchResultsUpdating協議。這裡面hehearray是我們的資料來源,searchList是我們搜尋時候的資料來源,不多說了直接上程式碼吧!
之前我看到有人使用UISearchDisplayController,其實這個在ios8中已經被UISearchController代替掉,而且實現起來更加簡單,不過用UISearchDisplayController會有一個警告
如圖
這個警告不用我解釋了吧,意思就是在ios8.0的時候UISearchDisplayController就已經被UISearchController替代了!好了,我們還是看程式碼吧!
searchTableViewController.h檔案程式碼
#import "searchTableViewController.h"
@interface searchTableViewController ()<UISearchResultsUpdating>
@property(nonatomic,strong)NSMutableArray *hehearray;
@property (nonatomic, strong) UISearchController *searchController;
@property (strong,nonatomic) NSMutableArray *searchList;
@end
@implementation searchTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
for (int i=0; i<50; i++) {
[self.hehearray addObject:[NSString stringWithFormat:@"呵呵%d",i]];
}
_searchController=[[UISearchController alloc]initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.dimsBackgroundDuringPresentation = NO;
_searchController.hidesNavigationBarDuringPresentation = NO;
_searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
self.tableView.tableHeaderView = self.searchController.searchBar;
}
-(NSMutableArray *)hehearray
{
if (_hehearray==nil) {
_hehearray=[NSMutableArray array];
}
return _hehearray;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.searchController.active) {
return [self.searchList count];
}else{
return [self.hehearray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *[email protected]"cellforappliancelist";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:dentifier];
}
if (self.searchController.active) {
[cell.textLabel setText:self.searchList[indexPath.row]];
}
else{
[cell.textLabel setText:self.hehearray[indexPath.row]];
}
return cell;
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = [self.searchController.searchBar text];
NSPredicate *preicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", searchString];
if (self.searchList!= nil) {
[self.searchList removeAllObjects];
}
//過濾資料
self.searchList= [NSMutableArray arrayWithArray:[_hehearray filteredArrayUsingPredicate:preicate]];
//重新整理表格
[self.tableView reloadData];
}
ok,看下執行效果
搜尋功能
為什麼呢,其實過濾程式碼在這
NSString *searchString = [self.searchController.searchBar text];
NSPredicate *preicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", searchString];
if (self.searchList!= nil) {
[self.searchList removeAllObjects];
}
//過濾資料
self.searchList= [NSMutableArray arrayWithArray:[_hehearray filteredArrayUsingPredicate:preicate]];
下面我們來具體看下過濾方法吧
NSPredicate *preicate = [NSPredicate predicateWithFormat:@”SELF CONTAINS[c] %@”, searchString];
這句話就是告訴在hehearray陣列中找到包含搜尋框中你輸入的字串的資料,放在searchlist數組裡面。
下面我來列舉一些,更多的篩選方法。其實中間的SELF就相當於代表hehearray自身,SELF CONTAINS[c] %@這些字串就像sql語句一樣,相信學過sql的人最熟悉了!
//找到與searchString相似的資料
NSPredicate *preicate = [NSPredicate predicateWithFormat:@"SELF like %@", searchString];
//如果陣列中裝的是物件,我們可以篩選物件的屬性,比如這句就是找出陣列中物件age屬性大於searchString的資料,當然了,前提是我們需要定義searchString為int型別了
NSPredicate *preicate = [NSPredicate predicateWithFormat:@"SELF.age > %i", searchString];
一般篩選陣列都是找出物件,下面我們來做一個例子,篩選出我們想要的物件陣列
我們先建立一個person類
person.h檔案
#import <Foundation/Foundation.h>
@interface person : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)int age;
@end
然後我們在searchTableViewController.h檔案開始建立物件陣列
#import "searchTableViewController.h"
#import "person.h"
@interface searchTableViewController ()<UISearchResultsUpdating>
@property(nonatomic,strong)NSMutableArray *hehearray;
@property (nonatomic, strong) UISearchController *searchController;
@property (strong,nonatomic) NSMutableArray *searchList;
@end
@implementation searchTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
for (int i=0; i<20; i++) {
person *p=[[person alloc]init];
p.name=[NSString stringWithFormat:@"名字%d",i];
p.age=i;
[self.hehearray addObject:p];
}
[self.tableView reloadData];
_searchController=[[UISearchController alloc]initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.dimsBackgroundDuringPresentation = NO;
_searchController.hidesNavigationBarDuringPresentation = NO;
_searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
self.tableView.tableHeaderView = self.searchController.searchBar;
}
-(NSMutableArray *)hehearray
{
if (_hehearray==nil) {
_hehearray=[NSMutableArray array];
}
return _hehearray;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.searchController.active) {
return [self.searchList count];
}else{
return [self.hehearray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *[email protected]"cellforappliancelist";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:dentifier];
}
if (self.searchController.active) {
person *p=self.searchList[indexPath.row];
cell.textLabel.text=p.name;
cell.detailTextLabel.text=[NSString stringWithFormat:@"%d",p.age];
}
else{
person *p=self.hehearray[indexPath.row];
cell.textLabel.text=p.name;
cell.detailTextLabel.text=[NSString stringWithFormat:@"%d",p.age];
}
return cell;
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = [self.searchController.searchBar text];
NSPredicate *preicate = [NSPredicate predicateWithFormat:@"SELF.name CONTAINS[c] %@", searchString];
if (self.searchList!= nil) {
[self.searchList removeAllObjects];
}
//過濾資料
self.searchList= [NSMutableArray arrayWithArray:[_hehearray filteredArrayUsingPredicate:preicate]];
//重新整理表格
[self.tableView reloadData];
}
@end
我們篩選的是名字中包含搜尋框的資料
看下效果吧
這裡篩選的是名字中帶有3的資料,可不是age屬性中帶3的啊,是因為我用的i作為age屬性,碰巧了!
還有最重要的一個不要忘記做了,如果我們需要點選搜尋框中的資料,進行跳轉控制器,我們會發現,上方的搜尋框在下一個控制器中還會存在,這可不是一件好事情。怎麼解決呢?這就需要我們在view即將消失之前,移除我們的搜尋控制器了。看程式碼
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.searchController.active) {
self.searchController.active = NO;
[self.navigationController setNavigationBarHidden:NO animated:YES];
[self.searchController.searchBar removeFromSuperview];
}
}