UISearchBar和 UISearchDisplayController的使用
感觉好多文章不是很全面,所以本文收集整合了网上的几篇文章,感觉有互相补充的效果。
如果想下载源码来看:http://code4app.com/search/searchbar 。本源码与本文无关
1、searchBar
本例子实现布局:上面是一个navigationController,接下来一个searchBar,下面是tableView
searchBar这个控件就用来搜索tableView上的数据
[[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
UISearchDisplayController这个控件很强大,它初始化是基于searchBar的,里面有些效果很不错,apple都封装好了,并且可以很好的支持实时搜索,即我们只需要将搜索出来的数据重新赋给array(这个array用来存储tableView数据),不需要reloadData,就会自动出来
其实reloadData也没用,为什么呢?因为搜索出来的结果显示在tableView上,该tableView并不是当前布局的那个tableView,而是另外一个,我猜测应该是UISearchDisplayController里面自带的,所以不要混淆了
特别是在tableView代理方法里,有时候需要判断代理方法传入的tableView是否为当前布局的tableView,因为也有可能是UISearchDisplayController里自带的,它们同样会触发代理方法
当点击searchBar时,它会自动上移并且遮住navigationController
经过测试,如果上面是navigationBar,则searchBar不会移动,但如果是UINavigationController自带过来的,则会上移覆盖
往往有的时候都是UINavigationController自带过来的,如果使用UISearchDisplayController,searchBar就会自动覆盖,这个情况我试了很多次,包括新创建了一个navigationBar盖在上面,但效果依然不好,对于这种情况,基于我目前的技术,只能舍弃UISearchDisplayController,单纯的用UISearchBar了,虽然效果差了一些,但需要实现的功能照样可以,比如实时搜索,除了重新赋值给array外,额外的操作就是需要reloadData了。
有时候点击searchBar时,右侧可能没有出现‘cancel/取消’按钮,这时需要调用下面的方法
- (void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated
相信看方法名字就知道是做什么的了
来源:http://www.cnblogs.com/mobiledevelopment/archive/2011/08/04/2127633.html
效果如图:
可以根据输入的关键字,在TableView中显示符合的数据。
图中分组显示和索引效果,前面的博文已经记录,不再赘述。下面的例子是基于前文的基础上修改的,所以文件名啥的,请参考前文。
第一步是在TableView上方添加一个Search Bar,这里有一点需要注意,必须先把TableView拖下来,留下空间放Search Bar,不要在Table View占满屏幕的情况下把Search Bar拖到Table View顶部。区别在于,使用后面的方法,Search Bar是作为Table View的Header部分添加的,而前面的方法,Search Bar是独立的。在添加索引功能时,如果作为Table View的Header添加,右侧的索引会遮住Search Bar的右边部分。Search Bar几个常用属性:
Placeholder是提示,就是hint属性,Corretion是自动修正,一般设为NO,即不修正,Show Cancel Button是显示取消按钮,我这里勾选。选中Search Bar的情况下切换到Connections Inspector面板,delegate与File’s Owner建立连接(我们会在ViewController中支持UISearchBarDelegate协议)。与前面几篇文章的例子相同,ViewController文件名为PDViewController.h和PDViewController.m。
第二步,添加Table View和Search Bar的Outlet.按住Control键,分别拖动Table View和Search Bar到PDViewController.h,添加Outlet
第三步,就是PDViewController代码:
PDViewController.h:
1 |
#import <UIKit/UIKit.h> |
PDViewController.m:
1 |
#import "PDViewController.h" |
mutableDeepCopy深复制的方法在NSDictionary+MutableDeepCopy定义,参考iOS/Objective-C开发 字典NSDictionary的深复制(使用category)
3、Search Bar and Search DisplayController的实现
新建Navigation-based Project。打开.xib文件,拖一个Search Bar and Search DisplayController 对象到Table View对象上方,如下图所示,选中File’s Owner ,打开Connections面板:
现在我们来创建Search Bar和SearchDisplay Controller的出口。打开Assistant Editor,按住ctrl键,将SearchDisplay Controller拖到ViewController 的头文件中。创建一个名为searchDisplayController的出口,然后点Connect。
同样的方法为Search Bar创建连接。现在ViewController的头文件看起来像这样:
#import <UIKit/UIKit.h> @interface RootViewController : UITableViewController { UISearchDisplayController *searchDisplayController; UISearchDisplayController *searchBar; NSArray *allItems; NSArray *searchResults; } @property (nonatomic, retain) IBOutlet UISearchDisplayController *searchDisplayController; @property (nonatomic, retain) IBOutlet UISearchDisplayController *searchBar; @property (nonatomic, copy) NSArray *allItems; @property (nonatomic, copy) NSArray *searchResults; @end |
你可能注意到,我初始化了两个NSArray。一个用于作为数据源,一个用于保存查找结果。在本文中,我使用字符串数组作为数据源。继续编辑.m文件前,别忘了synthesize相关属性:
@synthesize searchDisplayController; @synthesize searchBar; @synthesize allItems; @synthesize searchResults; |
在viewDidLoad 方法中,我们构造了我们的字符串数组:
- (void)viewDidLoad { [super viewDidLoad]; // [self.tableView reloadData]; self.tableView.scrollEnabled = YES; NSArray *items = [[NSArray alloc] initWithObjects: @"Code Geass", @"Asura Cryin'", @"Voltes V", @"Mazinger Z", @"Daimos", nil]; self.allItems = items; [items release]; [self.tableView reloadData]; } |
在Table View的返回TableView行数的方法中,我们先判断当前Table View是否是searchDisplayController的查找结果表格还是数据源本来的表格,然后返回对应的行数:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSInteger rows = 0; if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]){ rows = [self.searchResults count]; }else{ rows = [self.allItems count]; } return rows; } |
在tableView:cellForRowAtIndexPath:方法里,我们需要做同样的事:
// Customize the appearance of table view cells. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } /* Configure the cell. */ if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]){ cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row]; }else{ cell.textLabel.text = [self.allItems objectAtIndex:indexPath.row]; } return cell; } |
现在来实现当搜索文本改变时的回调函数。这个方法使用谓词进行比较,并讲匹配结果赋给searchResults数组:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope { NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", searchText]; self.searchResults = [self.allItems filteredArrayUsingPredicate:resultPredicate]; } |
接下来是UISearchDisplayController的委托方法,负责响应搜索事件:
#pragma mark - UISearchDisplayController delegate methods -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { [self filterContentForSearchText:searchString scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]]; return YES; } - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { [self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]]; return YES; } |
运行工程,当你在搜索栏中点击及输入文本时,如下图所示:
4、UISearchBar的使用以及下拉列表框的实现
在IOS混饭吃的同志们都很清楚,搜索框在移动开发应用中的地位。今天我们就结合下拉列表框的实现来聊聊UISearchBar的使用。本人新入行的菜鸟一个,不足之处请多多指教。直接上代码。
UISearchBar控件的声明:(在控制器DownListViewController中)
- @property (nonatomic,retain) UISearchBar* searchBar;
控件的初始化:
- _searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 320, 40)];
- _searchBar.placeholder = @"test"; //设置占位符
- _searchBar.delegate = self; //设置控件代理
当然,做完这些工作之后,我们还要在将控件添加到父视图之上,也可以把他设置成UITableView的tableHeaderView属性值,由于大家需求不一,这里就不再给出代码。
前面,我们设置了控件的代理,当然我们必须让控制器(DownListViewController)的 .h 文件实现 UISearchBarDelegate 协议,然后我们继续, 我们要在 .m 文件中实现协议方法:
- #pragma mark -
- #pragma mark UISearchBarDelegate
- //搜索框中的内容发生改变时 回调(即要搜索的内容改变)
- - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
- NSLog(@"changed");
- if (_searchBar.text.length == 0) {
- [self setSearchControllerHidden:YES]; //控制下拉列表的隐现
- }else{
- [self setSearchControllerHidden:NO];
- }
- }
- - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
- searchBar.showsCancelButton = YES;
- for(id cc in [searchBar subviews])
{
if([cc isKindOfClass:[UIButton class]])
{
UIButton *btn = (UIButton *)cc;
[btn setTitle:@"取消" forState:UIControlStateNormal];
}
} - NSLog(@"shuould begin");
- return YES;
- }
- - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
- searchBar.text = @"";
- NSLog(@"did begin");
- }
- - (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
- NSLog(@"did end");
- searchBar.showsCancelButton = NO;
- }
- - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
- NSLog(@"search clicked");
- }
- //点击搜索框上的 取消按钮时 调用
- - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
- NSLog(@"cancle clicked");
- _searchBar.text = @"";
- [_searchBar resignFirstResponder];
- [self setSearchControllerHidden:YES];
- }
至此,搜索框的实现就搞定了,怎么样简单吧。下面我们来讲讲下拉列表框的实现,先说说他的实现原理或者是思路吧。下拉列表框我们用一个控制器来实现,我们新建一个控制器SearchViewController.
- @interface SearchViewController : UITableViewController
- @end
在 .m 文件中,我们实现该控制器
- - (id)initWithStyle:(UITableViewStyle)style
- {
- self = [super initWithStyle:style];
- if (self) {
- // Custom initialization
- }
- return self;
- }
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- self.tableView.layer.borderWidth = 1;
- self.tableView.layer.borderColor = [[UIColor blackColor] CGColor];
- }
然后实现控制器的数据源,
- #pragma mark -
- #pragma mark Table view data source
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return 1;
- }
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- // 返回列表框的下拉列表的数量
- return 3;
- }
- // Customize the appearance of table view cells.
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- static NSString *CellIdentifier = @"Cell";
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
- }
- // Configure the cell...
- NSUInteger row = [indexPath row];
- cell.textLabel.text = @"down list";
- return cell;
- }
这样列表框的控制器就实现了。接下来我们就来看看怎么让出现、隐藏。这点我们利用UIView的动画效果来实现,我们在DownListViewController控制器中 增加一个方法:
- - (void) setSearchControllerHidden:(BOOL)hidden {
- NSInteger height = hidden ? 0: 180;
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationDuration:0.2];
- [_searchController.view setFrame:CGRectMake(30, 36, 200, height)];
- [UIView commitAnimations];
- }
我们只需调用该方法就可以了。现在我们看看DownListViewController的布局方法
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- _searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 320, 40)];
- _searchBar.placeholder = @"test";
- _searchBar.delegate = self;
- _tableview = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain];
- _tableview.dataSource = self;
- _tableview.tableHeaderView = _searchBar;
- _searchController = [[SearchViewController alloc] initWithStyle:UITableViewStylePlain];
- [_searchController.view setFrame:CGRectMake(30, 40, 200, 0)];
- [self.view addSubview:_tableview];
- [self.view addSubview:_searchController.view];
- }
这样一切都搞定了。
好了,总结一下:
我们用了两个控制器:DownListViewController(搜索框的实现 和 控制下拉列表框的出现与隐藏)和SearchViewController(下拉列表框的实现)。在DownListViewController中我们声明并初始化 UISearchBar和SearchViewController(高度开始设置为零),用动画来实现下拉列表框的出现与隐藏。
本文出自 “开发问道” 博客,请务必保留此出处http://izhuaodev.blog.51cto.com/6266344/1102408
UISearchBar和 UISearchDisplayController的使用的更多相关文章
- 如何在UINavigationBar上添加UISearchBar以及UISearchDisplayController的使用 --OC --iOS
那我们开始吧,下面是Sely写的一个Demo,分享给大家. 新建一个项目, UISearchDisplayController 的 displaysSearchBarInNavigationBar太死 ...
- UISearchBar和UISearchDisplayController
原文 http://hi.baidu.com/happywilma0118/item/e6d5730a499bba1b3a53eef8 UISearchBar继承自UIView.UIResponder ...
- iOS--- UITableView + UISearchDisplayController - - - - -实现搜索功能
iOS中UISearchDisplayController用于搜索,搜索栏的重要性我们就不说了,狼厂就是靠搜索起家的,现在越来越像一匹没有节操的狼,UC浏览器搜索栏现在默认自家的神马搜索,现在不管是社 ...
- iOS开发之直接使用UISearchBar
iOS开发中经常需要使用SearchBar,我们可以选择使用UISearchBar+UISearchController或者UISearchBar+UISearchDisplayController( ...
- iOS 用UISearchDisplayController实现查找功能
UISearchDisplayController是iOS中用于处理搜索功能的控制器,此控制器需要和UISearchBar结合使用 示例代码如下: // // WKRootViewController ...
- iOS UISearchDisplayController学习笔记
UISearchDisplayController和UISearchBar一起使用用来管理UISearchBar和搜索结果的展示.UISearchDisplayController提供了显示搜索结果的 ...
- UISearchController替换UISearchDisplayController
随着iOS 的升级,iOS 7的占有率更低了.Xcode 升级到Xcode 8之后,对iOS 应用支持的最低版本,iOS 7也被抛弃了.我在新项目中也是最低支持到iOS 8,因此工程里也是各种警告.首 ...
- iOS开发-搜索栏UISearchBar和UISearchController
iOS中UISearchDisplayController用于搜索,搜索栏的重要性我们就不说了,狼厂就是靠搜索起家的,现在越来越像一匹没有节操的狼,UC浏览器搜索栏现在默认自家的神马搜索,现在不管是社 ...
- [转] iOS开发-搜索栏UISearchBar和UISearchController
原文网址: http://www.cnblogs.com/xiaofeixiang/p/4273620.html?utm_source=tuicool iOS中UISearchDisplayContr ...
随机推荐
- [C#] 走进异步编程的世界 - 开始接触 async/await(转)
原文链接:http://www.cnblogs.com/liqingwen/p/5831951.html 走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 ...
- CSS3 chart
利用CSS3技术生成统计图. 原理:利用元素的百分比算出旋转度数.类似于斗地主时,手拿扑克牌的形状. 程序源码: <!DOCTYPE html> <html> <head ...
- JNDI全面总结(zz)
原理: 在DataSource中事先建立多个数据库连接,保存在数据库连接池中.当程序访问数据库时,只用从连接池中取空闲状态的数据库连接即可,访问结束,销毁资源,数据库连接重新回到连接池 ...
- lambda的Func<>函数
Func<int,int,int> fc=(int x,int y)=>x*y;Console.WriteLine(fc(5, 2)); //声明一个方法,返回值为int,参数是两个 ...
- 关于ARP攻击的原理以及在Kali Linux环境下的实现
关于ARP攻击的原理以及在Kali Linux环境下的实现 全文摘要 本文讲述内容分为两部分,前半部分讲述ARP协议及ARP攻击原理,后半部分讲述在Kali Linux环境下如何实现ARP攻击以及AR ...
- Ubuntu连接L2TP的VPN设置
作为程序猿,FQ查资料那是经常的事情.电信不知怎么的pptp方式连接不上.蛋疼!o(╯□╰)o没有办法自己只好折腾l2tp连接方式了\(^o^)/~ 1. 添加PPA sudo apt-add-rep ...
- C#基础之lock
1.lock的本质 实现线程同步的第一种方式是我们经常使用的lock关键字,它将包围的语句块标记为临界区,这样一次只有一个线程进入临界区并执行代码.下面第一段的几行代码是关于lock关键字的使用方式, ...
- Orchard 刨析:Caching
关于Orchard中的Caching组件已经有一些文章做了介绍,为了系列的完整性会再次对Caching组件进行一次介绍. 缓存的使用 在Orchard看到如下一段代码: 可以看到使用缓存的方法Get而 ...
- mac 80端口映射 配置
mac 80端口映射 配置 macbook 下,要绑定 80 端口的话. 一种方式是用 root 权限启动,即 sudo 启动服务进程.但 sudo 指令存在一定的安全问题,能不使用的情况下我们都尽量 ...
- 浅谈分治算法在OI中的应用
分治虽然是基本思想,但是OI中不会出裸分治让你一眼看出来,往往都是结合到找规律里面. 先来个简单的: 奇妙变换 (magic.pas/c/cpp) [问题描述] 为了奖励牛牛同学帮妈妈解决了大写中 ...