最近用到搜索功能。于是,经过不断的研究,终于,有点懂了。
那就来总结一下吧,好记性不如烂笔头!
搜索,无疑可以使用UISearchBar控件!
那就先了解一下UISearchBar控件吧!
UISearchBar控件就是要为你完成搜索功能的一个专用控件。它集成了很多你意想不到的功能和特点!
首先,还是来普及一下UISearchBar控件API相关的属性和方法吧!
UISearchBar属性相关
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];// 初始化,不解释
这么多属性,其实看起来多,你实际去操作事件一下,就发现很简单的!
绝大多部分都是定义一些外观的东西!了解了各个属性,一定能满足你设计出你想要的外观效果!!
然后,解释一下,我个人觉的比较有趣和重要的属性!
1.@property (nonatomic, readwrite, retain) UIView *inputAccessoryView;属性
例如:
[self.searchBar setInputAccessoryView:your_View];// 提供一个遮盖视图
当处于UISearchBar焦点状态下(输入框正要输入内容时),会有一个遮盖视图。
你翻看一下,iPhone手机上的电话本搜索功能。那个遮盖视图就是一个半透明的黑色View。
查看了一下API,是iOS 6.0 以及以后,新加入的!
那么就意味这 iOS 6.0 之前的系统是不兼容的。那么怎么才能达到这个类似的效果呢?
变通一下,其实,很简单:仍然设置一个按钮,初始状态下,该UIButton控件透明度设置为0;并且在控件取得焦点时,设置透明度为1。
小技巧:如果要设置这个属性,那么,就最好定义一个UIButton控件,这样,当点击该遮盖层的话,可以利用按钮事件,
设置:[self.searchBar resignFirstResponder];让搜索框放弃第一焦点。(iPhone电话薄也是这么做的,感觉很人性化)。
迷惑:还有一个小的问题:当我让UISearchBar显示取消按钮时,当我让UISearchBar失去焦点时,我的取消按钮也不能点击了。衰啊。
看了一下iPhone电话薄的UISearchBar,竟然可以也,找了很久,都不知道是怎么回事,大概苹果又开始玩私有API了吧。
解决方法:很暴力,但是很好用!在UISearchBar上原来取消按钮的位置上覆盖一个UIButton,设置成一样的。呵呵。可以了。
类似如下:
// 遮盖层
_btnAccessoryView=[[UIButton alloc] initWithFrame:CGRectMake(0, 44,BOUNDS_WIDTH, BOUNDS_HEIGHT)];
[_btnAccessoryView setBackgroundColor:[UIColor blackColor]];
[_btnAccessoryView setAlpha:0.0f];
[_btnAccessoryView addTarget:selfaction:@selector(ClickControlAction:)forControlEvents:UIControlEventTouchUpIns
[self.view addSubview:_btnAccessoryView];
// 遮罩层(按钮)-点击处理事件
- (void) ClickControlAction:(id)sender{
}
// 控制遮罩层的透明度
- (void)controlAccessoryView:(float)alphaValue{
}
2.@property(nonatomic,assign) id<</b>UISearchBarDelegate> delegate;属性
例如:
self.searchBar.delegate = self;
说到这个属性,就是设置委托了。
UISearchBarDelegate委托定义了很多关于,搜索框的一些操作数据的协议方法!
先来个,特写,把x协议的家庭成员列出来:
@protocol UISearchBarDelegate
@optional
- (BOOL)searchBarShouldBeginEdit
- (void)searchBarTextDidBeginEdi
- (BOOL)searchBarShouldEndEditin
- (void)searchBarTextDidEndEditi
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
- (void)searchBarSearchButtonCli
- (void)searchBarBookmarkButtonC
- (void)searchBarCancelButtonCli
- (void)searchBarResultsListButt
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndex
@end
这不需要解释吧,看方法名称就能了解!
我们来看一看,常用的委托方法吧。
#pragma mark - UISearchBarDelegate 协议
// UISearchBar得到焦点并开始编辑时,执行该方法
- (BOOL)searchBarShouldBeginEdit
}
// 取消按钮被按下时,执行的方法
- (void)searchBarCancelButtonCli
}
// 键盘中,搜索按钮被按下,执行的方法
- (void)searchBarSearchButtonCli
}
// 当搜索内容变化时,执行该方法。很有用,可以实现时实搜索
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString*)searchText;{
}
3.遍历UISearchBar控件的子控件,这样可以针对不同的子视图来设置外观了。
for(id subView in [self.searchBar subviews]){
当然,不是很全。也是入门的级别,见效了!
希望对你有所帮助!
UISearchBar继承自UIView、UIResponder、NSObject
属性:
autocapitalizationType————自动对输入文本对象进行大小写设置(包含4种类型,但是有时候键盘会屏蔽此属性)
autocorrectionType————自动对输入文本对象进行纠错。
backgroundImage————searchbar的背景图片,如果图片不是可伸缩的或者1点宽,则一般被平铺
barStyle————控件的样式
delegate————控件的委托,委托要遵从UISearchBarDelegate协议,默认是nil
keyboardType————输入时,键盘的样式
placeholder————半透明的提示文字,输入搜索内容消失
prompt————显示在控件顶部的一行提示文字
text————控件上面的显示的文字
showsBookmarkButton————是否在控件的右端显示一个书的按钮(输入文字时消失)
showsCancelButton————是否显示cancel按钮(默认是显示)
showsSearchResultsButton————是否在控件的右端显示搜索结果按钮
searchResultsButtonSelected————搜索结果按钮是否被选中
tintColor————bar的颜色(具有渐变效果)
translucent————指定控件是否会有透视效果
scopeButtonTitles————搜索栏下部的选择栏,数组里面的内容是按钮的标题
selectedScopeButtonIndex————搜索栏下部的选择栏按钮的个数
showsScopeBar————控制搜索栏下部的选择栏是否显示出来(需设置为YES 才能使用scopebar)
UISearchBar不执行搜索行为,必须使用delegate,当输入搜索文本、点击button按钮后,代理的方法会完成搜索对应的操作。
1.编辑输入事件:
2.点击按钮事件:
3.Scope按钮事件:
利用UISearchBar的委托事件 textDidChange, 当在搜索框中输入完成后,如果输入的文本长度>0,可以调用自己的搜索方法,得到搜索结果,然后再reloadData,刷新一下。如果输入文本长 度<0,则需要恢复到原始数据。这个方法可以在边输入搜索文本边显示结果。 如果需要按“search”按钮再搜索,则将上述操作放在searchBarSearchButtonClicked中。
利用UISearchDisplayController可以简化很多操作,也能达到搜索的目的。
属性:
active————是搜索界面可视化,默认为no,可用setActive方法设置.
delegate————委托
searchBar————在searchdisplaycontroller初始化后,searchbar是不可修改的,是readonly属性的.
searchContentController————管理搜索内容的试图控制器,一般是一个UITableViewController的实例,意思是针对一个UITableView的内容进行搜索
searchResultsDataSource————搜索结果的数据源
searchResultsDelegate————搜索结果的委托
searchResultsTableView————搜索结果要展示在哪个tableview中(read-only);
searchResultsTitle————搜索结果视图的title
初始化一个searchDisplayController:
UISearchBar * theSearchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width-50, 40)] autorelease];
theSearchBar.placeholder = @"enter province name";
theSearchBar.autocorrectionType = UITextAutocorrectionTypeNo;
theSearchBar.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
theSearchBar.scopeButtonTitles = [NSArray arrayWithObjects:@"All",@"A",@"B",@"C",@"D" ,nil];
theSearchBar.showsScopeBar = YES;
theSearchBar.keyboardType = UIKeyboardTypeNamePhonePad;
theSearchBar.showsBookmarkButton = YES;
tableView.tableHeaderView = theSearchBar; //将searchBar添加到tableView的头,注意滚动出屏幕后,搜索框也不在了,只出现在首页
UISearchDisplayController * searchdispalyCtrl = [[UISearchDisplayController alloc] initWithSearchBar:theSearchBar contentsController:self];
searchdispalyCtrl.active = NO;
searchdispalyCtrl.delegate = self;
searchdispalyCtrl.searchResultsDelegate=self;
searchdispalyCtrl.searchResultsDataSource = self;
使用UISearchDisplayDelegate的委托方法进行搜索操作:
1.搜索状态改变:
2.装载和卸载tableview:
3.显示和隐藏tableview:
4.搜索条件改变时响应:
searchDisplayController 自身有一个searchResultsTableView,所以在执行操作的时候首先要判断是否是搜索结果的tableView,如果是显示的就是搜索结 果的数据,如果不是,是TableView自身的view,则需要显示原始数据。
if(tableView == self.searchDisplayController.searchResultsTableView)
{
arr = [self.filterContent valueForKey:key]; //搜索结果
}
else
{
arr = [self.localresource valueForKey:key]; //原始数据
}
这样就不需要每次都realoadData了。
一 个很好的实例可以参考:http://developer.apple.com/library/ios/#samplecode /TableSearch/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007848
UISearchDisplayController 是苹果专为 UITableView 搜索封装的一个类。
里面内置了一个 UITableView 用于显示搜索的结果。它可以和一个需要搜索功能的
controller 关联起来,其它的像原 TableView 和搜索结果 TableView 的切换, mask 的显示等等都
封装好了,使用起来非常非常的简单。特别是要实现全屏搜索时使用最多。
全屏搜索的意思是如果你用了 NavigationBar 当点击搜索框时 TableView 会自动弹上去覆盖
NavigationBar,达到一种全屏搜索的效果,这一切 UISearchDisplayController 都封装好了,如果自己
写就比较麻烦一些。
关键代码:
@interface MainViewController : UITableViewController{ NSArray *data; NSArray *filterData; UISearchDisplayController *searchDisplayController; }
- (void)viewDidLoad { [super viewDidLoad]; UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width , 44)]; searchBar.placeholder = @"搜索"; // 添加 searchbar 到 headerview self.tableView.tableHeaderView = searchBar; // 用 searchbar 初始化 SearchDisplayController // 并把 searchDisplayController 和当前 controller 关联起来 searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self]; // searchResultsDataSource 就是 UITableViewDataSource searchDisplayController.searchResultsDataSource = self; // searchResultsDelegate 就是 UITableViewDelegate searchDisplayController.searchResultsDelegate = self; }
/* * 如果原 TableView 和 SearchDisplayController 中的 TableView 的 delete 指向同一个对象 * 需要在回调中区分出当前是哪个 TableView */ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (tableView == self.tableView) { return data.count; }else{ // 谓词搜索 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self contains [cd] %@",searchDisplayController.searchBar.text]; filterData = [[NSArray alloc] initWithArray:[data filteredArrayUsingPredicate:predicate]]; return filterData.count; } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellId = @"mycell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; } if (tableView == self.tableView) { cell.textLabel.text = data[indexPath.row]; }else{ cell.textLabel.text = filterData[indexPath.row]; } return cell; }