标签:des style blog http color io os ar 使用
在移动应用程序的世界里,用户对信息获取的速度要求非常高!
iOS用户希望他们需要的信息能够迅速地,直观地展现在他们面前。
因为UITableView的上下滚动能让用户迅速,自然地浏览大量信息,许多基于UIKit的应用都使用了UITableView来组织信息。但如果信息量非常非常大,让用户上下滚动如此长的列表是非常没有效率的。所以一个搜索的功能就是必须的了。
幸运的是,UIKit里有一个叫做UISearchBar的组件,能让用户迅速的筛选有用的信息。
在这个教程里,你会学习如何将这个搜索的组件融入你应用中的UITableView,包括加入自选的范围栏,使得你的应用更好用!
今时今日,用户在应用里看到很长的列表时,都会期待一个搜索的功能。如果他们找不到搜索功能,他们会非常沮丧的!
但是,一但你对搜索栏有一定了解,特别是在读完这篇教程之后,你就不会觉得它有多难了。问题是UISearchBar并不是那么容易用。UISearchBar的文档并不全面,这对第一次使用UISearchBar的开发者可能会比较有挑战。
其实UISearchBar挺懒的。它本身不做任何搜索。UISearchBar会提供一个基本的iOS搜索栏界面。它就像一个中等干部一样,最在行的就是让别人做事情。(像我以前的老板一样!)
UISearchBar类用delegate协议的方式来告诉app的其他部分用户正在搜索 栏中做什么。你需要自己编写对比字符串和过滤搜索的函数。这一听起来有点吓人,但是自定义的搜索功能让你对搜索过滤有更多的控制。你能够根据自己app的 特点来修改搜索结果,让你的用户体验更迅速和智能的搜索。
在这个教程中,你将编写一个基于table view的有搜索功能的糖果app。(是的,好吃的糖果!)
首先,我们看看这个教程的概要:
准备好做糖果搜索了吗?那我们开始吧!
在XCode里,点击”File New Project…”然后选择”iOS Application Single View Application”。将project命名为”CandySearch”。请确保在”Use Storyboards”和”Use Automatic Reference Counting”的选项旁打钩。最后,确保device栏中你的选择是iPhone,然后将这个project保存到你认为合适的路径。
我们先清理掉一些默认加入的文件,这样我们才能从零开始。在XCode左边的Project Navigator中多选ViewController.h和ViewController.m,点击鼠标右键打开菜单,选择Delete,然后点击”Move to Trash”(移放到垃圾桶)。点击打开MainStoryboard.storyboard,选中里面唯一的view controller(视图控制器)然后删除它。
现在我们开始重新按自己的要求来构建这个project。首先从storyboard开始。 从位于XCode右侧栏下方的Object Browser(对象浏览器)中拖出一个Navigation Controller(导航控制器)到storyboard(故事版)中。这会生成两个view,一个代表那个navigation controller(导航控制器)本身,另一个是UITableView。这个UITableView将成为我们程序的第一个用户看见的视图。
最后还需要加入一个视图控制器来控制当用户搜索列表时显示的详细内容视图。将一个View Controller对象拖入故事版(storyboard)中。你需要将这个视图控制器与UITableView的视图控制器联系起来。按住 control键然后从Table View点击拖动至那个新的视图控制器,在弹出的manual segue窗口中选择“Push”做为视图替换的模式。现在,你的project应该和下图类似:
下面你将创建一个数据模型类来保存每种糖果的类型和名字等信息。
创建一个新的文件并使用“iOS Cocoa Touch Objective-C class”模板。将这个类命名为Candy,并将它设为NSObject的子类。
打开Candy.h文件并将其内容改为如下:
这个类的对象有两个property(属性),一个是糖果的种类,另一个是糖果的名字。当用户搜索糖果时,你会用糖果的名称和用户输入的字符串进行比较。而糖果的种类只有在教程后面使用范围搜索时才会有用。
将Candy.m文件的内容改为如下:
上面加入的方法是用来初始化你的Candy类对象的。这个方法需要一个种类和名称的字符串。你将会将这些Candy对象展示在列表中,让用户可以轻易使用你的搜索功能来过滤显示的内容。
现在我们可以开始设置UITableView了。
下面我们将设置一个UITableView。用“iOSCocoa TouchObjective-C class ”模板创建一个新的文件,命名为CandyTableViewController,并将其设为UITableViewController的子类。
我们先添加一个数组来储存数据。打开CandyTableViewController.h文件并在@interface一行下面加入:
我们对CandyTableViewController.m文件进行一些简单的修改,只为了先完成一个示范性的列表。首先,清理掉一些我们不需要的模板自带的代码。将“(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath”以及其之后一直到文件最后一段(除了@end)的代码全部删除。
同时删除numberOfSectionsInTableView:方法,因为我们不需要用到它。
在文件顶端,导入Candy.h头文件,让我们的控制器知道这个数据模型:
然后在“@implementation”下面加入如下代码:
在viewDidLoad方法中,删除模板自带的备注并加入下面的代码来提供示范性数据:
将tableView:numberOfRowsInSection:的内容修改为如下:
|
在最后一个“@end”前加入下面代码:
首先,你告诉列表控制器每一行应该显示什么。然后从candyArray数组中通过indexPath来获取相应的Candy对象,然后用这个Candy对象的内容添入相应的行中在列表视图中显示出来。首先,你告诉列表控制器每一行应该显示什么。然后从candyArray数组中通过indexPath来获取相应的Candy对象,然后用这个Candy对象的内容添入相应的行中在列表视图中显示出来。
你还需要在storyboard中做一些设置,上述的代码才会有效。打开MainStoryboard.storyboard文件,选择Root
View Controller然后在Identity Inspector(右边设置栏上方的第三栏)中将它的类改为CandyTableViewController。
接着在左手工具栏点击选择table view,然后选择Connections Inspector(右边工具栏上方的第六栏)。将dataSource和delegate与Candy Table View Controller连接起来(点击dataSource和delegate旁的圆点然后拖至Candy Table View Controller)。
双击”Root View Controller”标题并将其改为”CandySearch”。
保存并编译运行。你的table view应该显示我们输入的示范数据!糖果太多,时间太少。我们需要一个搜索栏!
现在是时候设置UISearchBar了!打开storyboard(故事版)文件然后将一个“Search Bar and Search Display Controller”对象拖入到table view controller中。注意,对象库中还有一个“Search Bar” 对象,那不是我们想要的。将搜索栏放在导航栏和Table View之间。
小贴士:不 知道什么是“Search Display Controller”(搜索显示控制器)?根据苹果自己的文档记载,一个搜索显示控制器用来控制一个搜索栏以及一个table view。这个table view会显示搜索过滤后的信息。而这些信息来源于另一个视图控制器。也就是说,在我们的情况下,你的“search display controller”(搜索显示控制器)需要知道那个table view controller控制的那些示范数据。然后在搜索显示控制器自己的table view中显示搜索过滤后的结果。这个table view会覆盖table view controller的视图,这样用户只能看到过滤后的结果。
在storyboard界面下的Attributes inspector栏,请花点时间浏览一下Search Bar对象的各种属性。就算你不需要用到它们,但了解UIKit组件的各种属性也是有价值的。
如果你在这个属性旁打钩,搜索栏右边就会出现一个灰色按钮。这个按钮可以用来显示最近几次的搜索,或者上次搜索的结果。这个按钮的的功能可以通过Search Bar Delegate内的方法来控制。
注意: 总是清楚地知道你有什么选择能提高开发效率。所以以后在iOS的开发中,你应该记得花时间看看所有有可能用到的选项设置。
在完成storyboard的相关设置后,我们需要写一些代码来让搜索栏运作起来。打开CandyTableViewController.h文件并将:
改为:
这里我们将theUISearchBarDelegate类和UISearchDisplayDelegate类加入到CandyTableViewController类中。
并且,加入一个搜索栏的IBOutlet以及一个叫做”filteredCandyArray”的数组来储存搜索的结果。
别忘了在CandyTableViewController.m文件中“synthesize”这些新的属性:
现在你的代码中有一个outlet了,你需要将storyboard中的搜索栏和这个 outlet连接起来。打开故事版文件,选择“Candy Table View”控制器,打开“Connections Inspector”栏然后从candySearchBar outlet拖一根线出来和搜索栏连接起来:
编译并运行,你应该能在模拟器中看到那个搜索栏,只是它似乎不工作!你需要使用那个filteredCandyArray数组。
首先你需要初始化那个NSMutableArray。你可以将它的初始大小设为candyArray数组的大小,因为你不可能有比原来数组更大的过滤后的数组。将下面的代码加到CandyTableViewController.m文件的viewDidLoad方法中我们设置candyArray的地方,但是在[self.tableView reloadData]之前:
将下面的代码加入到文件的尾部:
上面的方法会根据搜索内容来过滤candyArray数组,并将结果放置到清空后的filteredCandyArray数组中。在清空filteredCandyArray后,我们用NSPredicate来过滤candyArray数组。
NSPredicate可以根据一个简单的条件字符串来过滤一个数组。注意NSPredicate的格式:
看起来很复杂啊?别怕,这其实很简单的。SELF.name指的是数组中每一个Candy对 象的“name”属性。”contains[c]“会让predicate搜索“name”属性中的字符串,看看有没有和后面提供的 “searchText”一样的字符串。大小写有别。
接着,将下面的代码加到文件末端:
上面的代码使得UISearchDisplayController Delegate的两个方法在用户改变搜索内容时会去调用实际过滤内容的函数(filterContentForSearchText)。
第一个方法在用户改变搜索栏里的字符串时就会被调用。第二个方法则在范围栏改变时被调用。你还没有在app中添加这个范围栏,所以这个方法只有在教程后面加入范围栏后才会有用。
编译并运行你的程序;你会发现搜索栏还是不能用,怎么回事呢?这是因为你还没有编写代码来让cellRowForIndexPath:方法知道什么时候应该用一般的数据,什么时候用过滤后的数据。将:
改为:
上面的代码检查现在现实的列表视图属于普通列表还是搜索后的列表。如果是搜索列表的话,视图 中实际显示的数据应该来自filteredCandyArray。否则,数据应该来自那个完整的数组。Display Controller会自动负责显示和隐藏相应的列表,所以我们只需要提供正确的(过滤或者没有过滤过的)数据,列表视图就会正确地显示出来。
numbersOfRowsInSection:方法也需要一些修改,因为过滤后的数组的长度显然和没过滤过的数组不一样。将numbersOfRowsInSection:的内容改为如下:
编译并运行程序。你的搜索栏已经可以使用了!不信你可以搜索一下你想要的糖果名字。
注意: 你或许也注意到 numberOfRowsInSection:方法中用来检查现在显示的列表视图的if/else逻辑在很多其他地方也需要。忘了做这个检查或导致奇怪的 bug。你只需要记住搜索过的内容会显示在一个另外的列表视图中。两个列表视图完全是分开的两个视图,苹果的设计让用户难以察觉这个区别。所以导致许多开 发者的误解。
类似刚才的情况,在详细视图中,详细视图控制器也需要知道现在使用的是哪一个列表视图:有所有内容的视图,或是有过滤后内容的视图。将下面的代码加入到CandyTableViewController.m文件中:
打开storyboard并确保连接糖果列表视图控制器与详细视图控制器的segue的identifier是”candyDetail”。编译并运行程序,当你点击列表视图中的任意一行时,那个糖果的详细信息就会显示在切入的详细视图中。
我们还可以通过糖果的种类来进一步缩小搜索范围。我们的糖果数据总共有三类(巧克力,硬糖和其他)。
首先,在storyboard中加入一个范围栏。来到CandySearch视图控制器并点 击选择搜索栏。在 attributes inspector(属性设置栏)中,在”Shows Scope Bar”选项旁打勾。然后将范围栏的标题改为:”All”, “Chocolate”, “Hard” ,和 “Other”。(你可以点击+按钮来加入更多的种类,双击来修改标题)。你的屏幕应该和下图类似:
下面我们需要修改CandyTableViewController.m文件中的filterContentForSearchText:方法,让它在过滤搜索时也会考虑选中的类别:
上面的代码使用了一个新的NSPredicate,叫做scopePredicate。如果选中的类别为“All”,我们则不做任何进一步的过滤。
编译并运行程序。范围栏应该已经出现在视图里了。但是我们在没有搜索时是不应该看到这个范围栏的。将下面的代码加入到viewDidLoad方法的顶端(就则调用super之后):
编译并运行。现在,你的范围栏应该和下图类似:
如果你注意苹果自带的音乐app,那里面音乐列表的搜索栏一开始是隐藏起来的。这样你的列表试图就会有更多的空间。在viewDidLoad方法中,你刚才加入代码的下方加入下面的代码:
因为你的搜索栏一开始是隐藏起来的,我们应该加入一个按钮来让用户知道列表视图有搜索功能。
首先,我们应该加入一个IBAction。 将下面的代码加入到CandyTableViewController.m文件的低端:
将下面的方法定义加入到CandyTableViewController.h文件:
现在打开storyboard,在导航栏加一个Bar Button Item(栏按钮)。在Attributes Inspector(属性设置栏),将identifier的值改为“search”,这样那个按钮就会用苹果默认的放大镜做为图标。然后在 connections inspector(链接设置栏),将那个按钮和goToSearch:方法联系起来。
这样就好了!你的“Search”按钮应该能用了。编译并运行:
如果看到和上图类似的界面,你已经大功告成了!
本文转自:http://www.lanou3g.com/blog/post-222.html
标签:des style blog http color io os ar 使用
原文地址:http://www.cnblogs.com/zhangbingboke/p/4031484.html