顯示廣告
隱藏 ✕
看板 Knuckles_note
作者 Knuckles (站長 那克斯)
標題 [Xcode] 加上 Search Bar 搜尋資料
時間 2014年09月17日 Wed. AM 02:13:43


 
例如要做搜尋看板的功能

在 storyboard 新增一個 Table View Controller 頁面後
拉一個 Search Bar and Search Display Controller 到 Table View 的上方
[圖]
 

新增類別 BoardSearchViewController
subclass: UITableViewController

在 storyboard 上的 TableViewController
將 identity 設定的 custom class 設為 BoardSearchViewController
[圖]
 

修改 BoardSearchViewController.m

加上兩個 private 變數: boardList 、 boardSearchResult
用來存載入的看板清單和經過搜尋字串過濾後的看板清單

@implementation BoardSearchViewController
{
    NSMutableArray *boardList;
    NSArray *boardSearchResult;
}


新增一個過濾清單用的成員函數

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *predicate = nil;
    if([searchText length]==1){ //只有一個字元的話找開頭就好
        predicate = [NSPredicate predicateWithFormat:@"name beginswith[c] %@", searchText];
    }else{
        predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
    }
    boardSearchResult = [boardList filteredArrayUsingPredicate:resultPredicate];    
}


在 search bar 輸入字串時會執行這個方法,並更新顯示清單
在這邊執行過濾清單的成員函數 - filterContentForSearchText:searchText:

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentForSearchText:searchString
                               scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                      objectAtIndex:[self.searchDisplayController.searchBar
                                                     selectedScopeButtonIndex]]];
    return YES;
}

其中 scope 是指如果有在 Search Bar 的屬性設定加上 Scope Titles 的話
[圖]
 
可以取得使用者點選了要搜尋的範圍為何


設定 table view 中 row 的數目
在預設模式和搜尋模式要分開設定
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [boardSearchResult count];
    } else { //非搜尋模式時顯示所有看板
        return [boardList count];
    }
}


每個 row 裡的 cell 要顯示的內容
在預設模式和搜尋模式要分開設定
注意在搜尋模式取得 cell 時,tableView 要改成 self.tableView,不然程式會掛掉

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"BoardSearchResultCell" forIndexPath:indexPath];
   
    NSDictionary *board;
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        board = [boardSearchResult objectAtIndex:indexPath.row];
    } else { //非搜尋模式時顯示所有看板
        board = boardList[indexPath.row];
    }
   
    cell.textLabel.text = board[@"name"];
   
    return cell;
}


參考:



修改 UISearchResultTableView 的顏色

要新增 UISearchDisplay 的 delegate 函數

在 BoardSearchViewController.h 的 @interface 這行後面加上 <UISearchDisplayDelegate>
像這樣:
@interface BoardSearchViewController : UITableViewController <UISearchDisplayDelegate>

然後在 BoardSearchViewController.m 加上 delegate 函數

//當 UISearchResult 顯示後會執行此函數
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView{
    //修改 UISearchResults 的背景色和分隔線顏色
    tableView.backgroundColor = [UIColor blackColor];
    tableView.separatorColor = [UIColor darkGrayColor];
}


=========== 錯誤解決記錄 =============
執行程式時,只要在 search bar 輸入字串,程式就掛掉
錯誤訊息: Assertion failure in -[UISearchResultsTableView dequeueReusableCellWithIdentifier:forIndexPath:]
參考:
在用reusable identifier取得 cell 時,
tableView 要改成 self.tableView,不然程式會掛掉  

UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"BoardSearchResultCell" forIndexPath:indexPath];

如果預設模式時Row的數目比搜尋模式時少,在搜尋模式時會掛掉
只要在搜尋模式時,取得 cell 的方式改為

UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"BoardSearchResultCell"];

也就是將後面的 forIndexPath:indexPath 拿掉即可





--
※ 作者: Knuckles 時間: 2014-09-17 02:13:43
※ 編輯: Knuckles 時間: 2017-04-19 17:17:57
※ 看板: KnucklesNote 文章推薦值: 0 目前人氣: 0 累積人氣: 1108 
分享網址: 複製 已複製
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇