
この記事では、「検索」ボタンがクリックされるのを待たずに、検索文字列に入力されたテキストに基づいて検索結果を動的に生成する必要がある場合、ユーザーがクエリをすばやく入力するときに、DataSource UITableViewで検索を実装する方法を紹介します。
そのため、検索用のUISearchBarを持つテーブルがあります。 この例では、SQLiteデータベースはDataSourceとして機能します(たとえば、APIアクセスを備えた外部データソースにすることもできます)。 データベースには多くのレコード(数千)が含まれており、検索には約0.5秒かかります。
ユーザー
がクエリを
入力したときに検索結果を動的に生成するには、
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchTextデリゲートUISearchBar:を実装する必要があります。
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { __weak ProductPickerTableViewController *weakSelf = self; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ const char *label = "ru.example.unique.search"; weakSelf.searchDispatchQueue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL); }); dispatch_async(self.searchDispatchQueue, ^{ NSArray *searchProducts = nil; if ([searchText length]) { searchProducts = [self.food productsBySearchPhrase:searchText]; } dispatch_async(dispatch_get_main_queue(), ^{ weakSelf.searchProducts = searchProducts; [weakSelf.tableView reloadData]; }); }); }
コントローラーのデータソースはメインスレッドで満たされていません。そうでないと、インターフェイスの速度が低下します。 データを受信した後、テーブルビューを更新します(常にメインスレッドで)。
このようなアプローチには1つの欠点があります-検索文字列が変更されるたびに、データベース検索メソッドが呼び出されます(またはAPIを介したネットワーク要求が送信されます)。ユーザーがクエリをすばやく入力するか、Backspaceキーを押して削除する場合、これはまったく不要です。
私が最初に思いついたのは、たとえばエントリ間で0.1秒が経過した場合にのみ検索メソッドを呼び出すこと(データソースを更新すること)でした。 githubのオープンスペースで、キャンセルされたブロックの実装が見つかりました。
キャンセルされたブロックのこの実装を使用して、UISearchBarデリゲートメソッドを次のように書き換えることができます。
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { __weak ProductPickerTableViewController *weakSelf = self; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ static const char *label = "ru.example.unique.search"; weakSelf.searchDispatchQueue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL); }); double searchDelay = 0.1; if (self.searchBlock != nil) {
変数searchDelayは、検索文字列に2文字を入力(または削除)する時間間隔に対応します。 バックスペースキーで検索文字列を消去するときに検索メソッドを繰り返し呼び出さないようにするには0.1秒で十分です。クエリをすばやく入力するには0.2〜0.3秒で十分です。
その結果、ユーザーの意見に即応する検索が得られます。