過去にもUISearchDisplayControllerについて少し書きましたが、どうしても意図した動作にならず、どうやってコードから扱うのか、というのが曖昧なままでした。
が、やっと動く最低限のコードがわかったのでメモです。
(ちなみに動作サンプルをGithubに上げてあります)
セットアップ
セットアップです。
ちなみにsearchDisplayController
はUIViewController
のreadonlyプロパティとしてすでに設定されているので再定義できません。
また、Appleのドキュメントを見ると、UISearchDisplayController
の初期化時に自動的に設定される、とあるのですがこの「初期化時」がなにを指しているのかが分かりませんでした。
(propertyではなく、普通にローカル変数で生成した場合は反応なし)
なので以下のようにセットアップしました。
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
self.searchBar.delegate = self;
self.searchBar.showsScopeBar = YES;
self.searchBar.showsSearchResultsButton = YES;
self.searchBar.scopeButtonTitles = @[@"test", @"hoge", @"foga"];
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar
contentsController:self];
self.searchController.delegate = self;
self.searchController.searchResultsDelegate = self;
self.searchController.searchResultsDataSource = self;
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds
style:UITableViewStylePlain];
self.tableView.tableHeaderView = self.searchBar;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.tableHeaderView = self.searchBar;
DataSource
searchDisplayController:shouldReloadTableForSearchString:
メソッドでYES
を返すと、searchResultsDataSource
にself
を設定しているため、通常のtableViewと同様にtableView:cellForRowAtIndexPath:
が呼ばれます。
その中で、以下のように分岐処理を書いて、検索中かそれ以外でソースを出し分けると適切に検索結果を表示してくれるようになります。
if ([tableView isEqual:self.searchController.searchResultsTableView]) { ... }
また、インクリメンタルサーチ的なことをやらず、非同期で検索などをさせたい場合は、searchResultsTableView
のreloadData
メソッドを適切なタイミングで読んでやることで結果を表示することができます。
てか、冷静に考えたら単純にUISearchDisplayControllerがメモリから解放されているから動いてなかっただけかも・・。なんか自動で設定されるとか色々な情報で混乱していた気がする( ;´Д`)