亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

【一步一步學IOS5 】 在表視圖中添加搜索欄

系統 2778 0

下面,我們來演示一下如何在Tab Bar項目基礎上添加一個搜索欄。通過搜索欄,App可以讓用戶指定搜索條件后,搜索菜單列表。

?

1.理解搜索欄顯示控制器(Search Display Controller)

?

你可以使用搜索顯示控制器(如 UISearchDisplayController 類)管理App中的搜索功能。搜索顯示控制器管理搜索欄(search bar)和表視圖(table view)的顯示,表視圖復雜顯示搜索結果。

?

當用戶開始搜索時,搜索顯示控制器將在原始的視圖之上,疊加搜索界面,并顯示搜索結果。有趣的是,在表視圖中顯示的結果是有搜索顯示控制器生成的。

?

和其它的視圖控制器一樣,你可以選擇編程創建搜索控制器,或者使用Storyboard簡單添加搜索顯示控制器到App中,我們采用后者。

?

2.在Storyboard 中添加搜索顯示控制器

?

在Storyboard 編程界面,拖拉Search Bar and Search Display Controller 對象到 Recipe Book 視圖控制器的導航條下面。如果操作正確,你應該看到的如下所示的界面:

?


【一步一步學IOS5 】 在表視圖中添加搜索欄

?

?在繼續之前,我們嘗試運行下App,界面效果如下。在沒有編寫任何新的代碼之前,你已經有一個搜索欄。輕拍搜索欄,將顯示搜索界面。但是,搜索并沒有顯示正確的搜索結果。


【一步一步學IOS5 】 在表視圖中添加搜索欄

?

3.搜索結果顯示原理解析?

?

在前面提到過,搜索結果顯示搜索顯示控制器(Search Display Controller)生成的表視圖中,

?

我們在開發視圖App時,我們實現了UITableViewDataSource協議,告訴表視圖有多少條數據行顯示,以及每一行的數據。

?

和UITableView 對象一樣,搜索顯示控制器生成的表視圖采用相同的方法,采用委托的方式,讓搜索欄和搜索結果交互。

?

?

一般而言,原始視圖控制器作為搜索結果數據源和委托的源對象,我們不必手動連接數據源(DataSource)和委托(Delegate)到視圖控制器上,

?

當我們插入搜索欄到Recipe Book 視圖控制器中時,將自動建立搜索顯示控制器(Search Display Controller)的連接。鼠標右鍵,點擊搜索顯示控制器(Search Display Controller)顯示連接信息。

?


【一步一步學IOS5 】 在表視圖中添加搜索欄

兩個表視圖(Recipe Book 視圖控制器中的表視圖 ?和 搜索結果表視圖)共享相同的視圖控制器,負責數據填充。在顯示表數據時,都會調用到

?

?

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{}

?

?

- (UITableViewCell *)tableView:(UITableView *)tableView

cellForRowAtIndexPath:(NSIndexPath *)indexPath {}

?

4.實現搜索過濾器

?

顯然,為了實現搜索功能,我們必須實現如下任務:

?

1.實現方法過濾菜單名稱,返回正確的搜索結果

2.更改數據源方法,區分不同的表視圖。如果傳入的tableView 是 Recipe Book 視圖控制器的表視圖,則顯示所有的菜單列表,如果傳入的是搜索結果表視圖,則僅僅顯示搜索結果。

?

首先,我們演示如何時間過濾器,這里,我們已經有一個數組存放所有的菜單列表了,我們需要創建另外一個數組存放搜索結果 - 命名為searchResults 數組。

?

?

@implementation RecipeBookViewController

{

? ? NSArray *recipes;

? ? NSArray *searchResults;

}



接著,添加一個新的方法負責處理搜索過濾功能,過濾功能是iOS App 中常見的任務。過濾菜單列表的直接方法是循環所有名稱,使用if語句過濾結果,這樣是實現并沒有任何錯誤。但是,iOS SDK 提供了一個更好的方法 - Predicate 負責搜索查詢。

通過使用NSPredicate (是Predicate對象的表現形式),可以簡化代碼。通過僅僅2行代碼,就可以搜索所有的菜單列表,返回匹配的結果:

- ( void )filterContentForSearchText:( NSString *)searchText scope:( NSString *)scope

{

? ? NSPredicate *resultPredicate = [ NSPredicate predicateWithFormat : @"SELF contains[cd] %@" ,searchText];

? ? searchResults = [ recipes filteredArrayUsingPredicate :resultPredicate];

}

?

基本上,一個Predicate,返回Boolearn值(true或false).你可以NSPredicate格式指定查詢條件,然后使用NSPredicate對象過濾數組中的數據。NSArray提供了filteredArrayUsingPredicate:方法,該方法返回一個新的數組,數組包含了匹配制定的Predicate的對象。Predicate 中 SELF 關鍵字 - SELF contains[cd]%@ 指向比較對象(如菜單名稱)。

?

操作符[cd]表示比較操作 - case 和 diacritic 不敏感。

?

?

?

5.實現搜索顯示控制器(Search Display Controller)委托

?

現在,我們已經創建了處理數據過濾的方法,但是如何調用該方法呢?

?

顯然,在用戶輸入搜索條件時,調用filterContentForSearchText: 方法。

?

UISearchDisplayController 類提供了 shouldReloadTableForSearchString: 方法,在搜索文本更改時,該方法會自動調用,因此,在RecipeBookViewController.m 文件添加如下方法:

?

?

- ( BOOL )searchDisplayController:( UISearchDisplayController *)controller shouldReloadTableForSearchString:( NSString *)searchString

{

? ? [ self filterContentForSearchText :searchString scope :[[ self . searchDisplayController . searchBar scopeButtonTitles ] objectAtIndex :[ self . searchDisplayController . searchBar selectedScopeButtonIndex ]]];

? ? return YES ;

}

?

?

6.在searchResultsTableView 顯示搜索結果

?

在前面解釋過,我們需要修改Data Source 方法,區分不同的表視圖(如Recipe Book 視圖控制器中的表視圖 ?和 搜索結果表視圖)。

?

區分表視圖是相當簡單的。

?

我們簡單標記tableView 對象和 searchDisplayController的 searchResultsTableView.?

?

如果相同,則顯示搜索結果。

?

代碼修改如下:

?

?

- ( NSInteger )tableView:( UITableView *)tableView numberOfRowsInSection:( NSInteger )section

{

? ? if (tableView == self . searchDisplayController . searchResultsTableView ) {

? ? ? ? return [ searchResults count ];

? ? } else {

? ? ? ? return [ recipes count ];

? ? }

}

?

?

?

?

- ( UITableViewCell *)tableView:( UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath

{

? ? static NSString *simpleTableIdentifier = @"RecipeCell" ;

?

? ? UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier :simpleTableIdentifier];

?

? ? if (cell == nil ) {

? ? ? ? cell = [[ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier :simpleTableIdentifier];

? ? }

?

? ? if (tableView == self . searchDisplayController . searchResultsTableView ) {

? ? ? ? cell. textLabel . text = [ searchResults objectAtIndex :indexPath. row ];

? ? } else {

? ? ? ? cell. textLabel . text = [ recipes objectAtIndex :indexPath. row ];

?

? ? }

?

? ? return cell;

}




7.再次運行App

當完成上述更新之后,再次運行App,搜索欄效果如下


8.處理搜索結果中的行選擇

盡管搜索功能正常了,但是它并沒有對行選擇進行處理。我們希望它和菜單表視圖一樣功能,

當用戶輕拍任一搜索記錄時,將切換到詳細視圖,顯示所選擇的菜單名稱。

之前,我們使用聯線(Segue)連接單元格和詳細視圖

現在,我們需要在Storyboard 中創建另外一個聯線,定義搜索結果和詳細視圖之間的切換。

問題是我們不能這樣操作,搜索結果表視圖是搜索顯示控制器(Search Display Controller)的一個私有變量,
它不可能使用Storyboard 處理搜索結果的行選擇。

然而,搜索結果控制器可以讓你使用委托(Delegate),和搜索結果表視圖的用戶選擇來交互。當用戶選擇一行時,將調用
didSelectRowAtIndexPath: 方法。

因此,我們需要實現如下方法:

- ( void )tableView:( UITableView *)tableView didSelectRowAtIndexPath:( NSIndexPath *)indexPath

{

? ? if (tableView == self . searchDisplayController . searchResultsTableView ) {

? ? ? ? [ self performSegueWithIdentifier : @"showRecipeDetail" sender : self ];

? ? }

}

?

我們簡單的調用preformSegueWithIdentifier: 方法,手動觸發showRecipeDetail 聯線。

?

在繼續編寫代碼之前,我們再次運行App。在你選擇任一搜索結果記錄時,App顯示詳細視圖,并帶有菜單名稱,

?

但是,菜單名稱并不總是正確的。

?

參考prepareForSegue: 方法,我們使用indexPathForSelectedRow 方法檢索所選indexPath屬性值。

?

前面提到過,搜索結果顯示在一個獨立的表視圖中,但是,在之前的prepareForSegue:方法中,我們總是從Recipe Book

?

視圖控制器的表視圖中檢索所選中的記錄行。

?

這就是為什么我們在詳細視圖中獲得錯誤的菜單名稱。為了取得搜索結果中正確的選擇,我們需要修改prepareForSegue:方法:

?

?

- ( void )prepareForSegue:( UIStoryboardSegue *)segue sender:( id )sender

{

? ? if ([segue. identifier isEqualToString : @"showRecipeDetail" ]) {

?

? ? ? ? NSIndexPath *indexPath = nil ;

?

? ? ? ? RecipeDetailViewController *destViewController = segue. destinationViewController ;

? ? ? ? if ([ self . searchDisplayController isActive ]) {

? ? ? ? ? ? indexPath = [ self . searchDisplayController . searchResultsTableView indexPathForSelectedRow ];

? ? ? ? ? ? destViewController. recipeName = [ searchResults objectAtIndex :indexPath. row ];

? ? ? ? } else {

? ? ? ? ? ? indexPath = [ self . tableView indexPathForSelectedRow ];

? ? ? ? ? ? destViewController. recipeName = [ recipes objectAtIndex :indexPath. row ];

? ? ? ? }

?

? ? }

}


我們首先判斷用戶是否使用搜索功能。當使用搜索功能時,我們從searchResultTableView 中檢索indexPath,這個是搜索結果的表視圖。否則,我們仍然從Recipe Book 視圖控制器中的表視圖獲取indexPath 屬性值。

好啦,再次運行App。搜索功能正常了。

【一步一步學IOS5 】 在表視圖中添加搜索欄
?

?

?

【一步一步學IOS5 】 在表視圖中添加搜索欄


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲国产精品久久久久久网站 | 777奇米视频| 久久国产精品-久久精品 | 四虎在线观看网址 | 中文字幕亚洲综合久久2 | 99久久这里只精品国产免费 | 黄色在线观看视频免费 | 国产精品天天影视久久综合网 | 久久久久久麻豆 | 2021天天干| 九九九网站| 色婷婷狠狠五月综合天色拍 | 国产精品福利午夜h视频 | 亚洲va久久久噜噜噜久久男同 | 亚洲国产精品yw在线观看 | 久久99热这里只有精品高清 | 久久久久久久亚洲精品 | 97福利视频| 久草在线视频首页 | 日本高清二区 | 爆操波多野结衣 | 国产福利在线观看精品 | 精品玖玖| 日韩影院久久 | 精品一区二区三区免费观看 | 久久综合一区二区三区 | 欧美日韩一区二区三区久久 | 国产色产综合色产在线观看视频 | 久久久久久天天夜夜天天 | 免费一级大毛片a一观看不卡 | 国产日韩在线看 | 激情综合在线观看 | 亚洲a视频 | 精品久久久久国产 | 久久96国产精品久久久 | 米奇777第四久久久99 | 成人a毛片手机免费播放 | 欧美黄色免费网址 | 伊人狼人视频 | 成人在线精品视频 | 国产在线原创剧情麻豆 |