IOS search bar 从IOS8开始发生了一些变化。有了新的使用方式。
IOS的search bar是这样工作的:
当用户点Search bar,它获得输入焦点后,会出现一个新的页面(ViewController),这个页面就是显示搜索结果的页面。当用户在search bar中输入的时候,这个页面就显示搜索结果。一般结果是显示在 table view中,所以这个搜索结果页面上一般会有个table view。
现在除了search bar之外
还多了一种选择:search controller (UISearchController)
使用search bar需按以下步骤:
1 创建或在Interface builder中拖一个search bar 控件
2 需要手动响应search bar的获取焦点事件,创建搜索结果页面,并把搜索结果页面显示出来。
3 响应search bar的文本框中的的文本改变事件,跟据当前的文本取得结果列表,显示在Table View中。
search controller中包含了search bar和搜索结果页面。搜索结果页面会在需页的时机自动显示,所search controller比单独用search bar更省事。
使用search controller的话,拖一个控件和手动创建,还有不小的差别。在Interface builder中拖一个search controller时,会自动带一个搜索结果页面,而手动创建时,需要手动指定搜索结果页面。
下图这个search bar就是直接拖了一个search controller到一个table view的头部。
可以看到,search controller的search bar嵌到了table view中。
当search bar获得输入焦点时的样子如下:
search bar默认会自动顶走导航栏而占据它的位置,当然这个可以设置search bar的属性禁止它这样做。当search bar获得输入焦点时,出现了半透明的页面,主界面成了半灰色。当你输入字符时,出现搜索结果页面,如下:
当然不论输入什么都不显示任何结果。因为显示结果完全是你自己控制的。你需要响应Search Bar的文本改变事件,在其中计算出搜索结果列表,把列表显示在table view中,用户才能看到结果。
在界面设计器中可以看到拖入search bar时,也增加了一个 view controller:
可以单独为这个view controller设置属性。
手动创建search controller,要调用UISearchController的初始化方法—
-(instancetype)initWithSearchResultsController:(nullable UIViewController *)searchResultsController;
其参数 searchResultsController是显示结果的页面。不同于拖控件,必须传一个结果页面给它才行。那么这个结果页面我们可以自行设计, 但大多数都用tableview来显示结果,所以只接用一个Table view controller一般就够了。
很多app对于搜索页是这样设计的:
在主页面的导航栏上有一个搜索按钮
页面1
当点击的时候进入另一个页面,在这个页面才看到search bar
页面2
并且还有可能有一些现成的关键词,都放在按钮里,点一下直接搜索那些关键词。当在search bar中输入的时候就显示出结果页面。
但是如果使用Search bar controller,而且又想把search bar显示在导航栏中的话,似乎是不可能实现的。Search bar controller的行为会变得很奇怪。这时候就要单独使用search bar了。
也就是说在上面的页面2中的search bar是一个单独的search bar。它的行为我们的得自己实现。我们响应它的获取输入焦点事件,在其中显示结果页面。结果页面一般是显示在导航栏之下的,所以结果页面不应是一个view controller,而直接用一个table view最行了。计算好这个table view的合适位置,显示出来即可。
要响应search bar 中的事件,当然是用协议和代理的方式。search bar的代理UISearchBarDelegate中有很多方法。大部分是用于通知代理发生了什么事。代理实现方法
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
就能响应开获取焦点事件,如:
(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{
//在导航栏下显示结果table view,应该用autolayout,此处省事直接减去了导航栏底部的y值
self.resultTV.frame=CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height-64);return YES;
}
resultTV是提前创建的table view。
代理中还有其它很多方法,可以让我们随时监测用户输入的变化,可以在每次变化时都计算新的结果并显示到table view中。