7

Web サービスからの非同期結果を処理する検索ディスプレイ コントローラーをセットアップしようとしています。基本的な部分は整っていますが、理解できない非常に奇妙な問題に遭遇しました。

非同期の検索表示コントローラーを装備するように思えますが、実際には次の 2 つのことを行う必要があります。

  1. searchDisplayController:shouldReloadTableForSearchString に対して NO を返す、および
  2. searchBarSearchButtonClicked を処理し、テーブルのリロードを開始します。

私はこれらの両方を行っていますが、私が見ているのは、#1 に従って NO を返しているにもかかわらず、検索バーに入力された最初の文字で検索ディスプレイ コントローラーがテーブルをリロードしていることです。入力された後続の文字ではリロードされません。

だから、私の質問は、ユーザーが入力している間に検索ディスプレイコントローラーがテーブルをリロードしようとしないようにするにはどうすればよいですか? (具体的には、最初に入力した文字)

この問題が他のいくつかの質問の一部として言及されているのを見てきましたが、問題に対する直接的な回答は見たことがありません。それを回避するためにたくさんの UI マングリングに頼る前に、何が起こっているのか、何が間違っているのかを理解したいと思います。

これは、問題を示すために私のコードを簡単に要約したものです。これを実行して検索バーに「abcde」と入力すると、「a」と入力した後に結果が「a #0」、「a #2」などとして表示されます。検索ボタンを押すまで、結果は再び更新されません。次に、「abcde #0」、「abcde #1」などと表示されます。もちろん、検索ボタンを押すまでは何も起こりません。

#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    return NO;
}

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
    return NO;
}


#pragma mark -
#pragma mark UISearchBarDelegate Methods

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [self.searchDisplayController.searchResultsTableView reloadData];

}


#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    cell.textLabel.text = [self.searchDisplayController.searchBar.text stringByAppendingFormat:@" #%d", indexPath.row]; 
    return cell;
}

ありがとう!(ちなみに、これは私がここで尋ねた最初の質問です。エチケットのポイントを見逃している場合はお知らせください:)

4

5 に答える 5

15

これは、UISearchDisplayController (SDC) が機能する方法です。ユーザーが最初の文字を searchBar に入力すると、searchTable がロードされて初めて表示され、ロードされます。メソッド「...shouldReloadTableForSearchString」および「...shouldReloadTableForSearchScope」を使用すると、後続の文字またはスコープの変更で searchTable を自動的にリロードするかどうかを制御できます。

最初のキャラクターで優れたユーザー エクスペリエンスを提供するために、次の両方を行いました。ちょっとした免責事項:私はこれらの両方の実装を持っていますが、これは単に私の記憶からの実装のためのフレームワークです. 詳細を見逃しているかもしれませんが、これでかなり近づくはずです。

オプション 1: 最初の文字が入力されたときに、searchTable に「読み込み中」のセルを表示します。

このオプションを使用すると、ユーザーが最初の文字を入力したときに SDC が searchResultsTableView を表示し、現在の検索/フィルター操作に関するステータスを表示できます。

  1. SDCデリゲートクラス定義で

    • iVar を追加するBOOL isLoading
    • iVar を追加するUITableView *searchTableView
  2. searchDisplayController:didLoadSearchResultsTableView

    • 設定searchTableView = tableView
  3. shouldReloadTableForSearchString/Scope

    • 設定isLoading = YES
    • メソッドを呼び出して、バックグラウンドでデータをロードします
    • いいえを返す
  4. バックグラウンド フィルターが完成したら:

    • 設定isLoading = NO
    • [searchTableView reloadData]
  5. さまざまな tableView デリゲート メソッドで、現在の検索結果がある場合、または結果がバックグラウンドで読み込まれている場合のステータスの表示方法に応答します。私がしたことは次のとおりです。

    • 現在の検索結果がある場合は、結果を表示します (バックグラウンドで読み込み/フィルタリングしている場合でも)
    • 検索結果がなく、isLoading == NO1 行を返し、セルに「一致なし」と表示される場合
    • 検索結果がなく、isLoading == YES1 行を返し、セルに検索アクティビティを表示する場合 (通常は UIActivityIndi​​catorView を使用します)

オプション 2: searchTableView を非表示にし、検索結果が読み込まれるまでその場所にオーバーレイ ビューを表示する

このオプションは、最初にロードされたときに searchTableView を非表示にし、検索/フィルターが完了した場合にのみ再表示します。テーブルを非表示にしてオーバーレイを表示している場合、searchResultsTableView で検索アクティビティを表示することを気にしないかもしれないことを最適化するために、これらは一緒に実行できるため、これをオプション 1 のアドオンとして定義しました。

  1. SDCデリゲートクラス定義で

    • オプション 1 と同じ
    • iVar を追加するUIView *searchTableOverlayView
  2. searchDisplayController:didLoadSearchResultsTableView

    • オプション 1 と同じ
    • アプリに適したUIを含むsearchTableViewの代わりにオーバーレイとして使用するUIViewを作成し、それをsearchTableOverlayView
  3. searchDisplayController:didUnloadSearchResultsTableView

    • リリースsearchTableOverlayView
  4. 「searchDisplayController:didShowSearchResultsTableView (may be able to do this insearchDisplayController:willShowSearchResultsTableView 」で

    • 表示する検索結果がある場合、またはisLoading == NO
      • seachTableOverlayView.hidden == YES
    • そうでなければ(もしisLoading == YES
      • searchTableOverlayView.frame == searchResultsTableView.frame
      • seachTableOverlayViewのサブビューとして追加searchTableVIew.superview
      • searchTableView.hidden = YES
  5. 背景フィルターが完成したら

    • オプション1と同じ
    • 表示する検索結果がある場合
      • searchTableCoverView.hidden = YES
      • searchResultsTableView.hidden = NO
    • そうしないと
      • searchResultsTableView.hidden = YES
      • searchTableCoverView.hidden = NO
  6. さまざまな tableView デリゲート メソッドで、現在の検索結果がある場合、または結果がバックグラウンドで読み込まれている場合のステータスの表示方法に応答します。私がしたことは次のとおりです。

    • オプション1と同じ
于 2011-03-17T17:41:39.423 に答える
0

残念ながら、これがまさにUISearchDisplayController機能の仕方だと思います。機能のさまざまなオプションを要求する場合は、Appleにバグレポートを提出する必要があります。

別の方法は、動作と同様に独自の組み合わせを作成するUISearchBarことです。そうすれば、より適切に制御できるようになります。UITableViewUISearchDisplayController

お役に立てれば!

于 2011-03-06T15:08:10.957 に答える
0

同じ問題に直面したとき、検索結果ビューにオーバーレイ ビューを配置しようとしました。それは私を助けませんでした。Apple が動作を変更したようで、ビューを通してセル区切りが輝いているのを見ました。最後に、私は良いアプローチを思いつきました。

最初、私の非同期検索クラスには、独自のオーバーレイ、進行状況、およびその他のビューがありました。UISearchDisplayController は、デリゲート メソッドの開始と終了の呼び出しにのみ使用され、デフォルトの検索フローに固執していました。ビューを表示するには、(init 呼び出しとして) 検索ビューを配置できる任意のサブビューを使用しました。

newView.frame = frame;
[view addSubview:newView];

次に、検索の進行状況ビューを変更するときにサブビューを使用します。

if (view == currentView)
    return;

view.frame = currentView.frame;
view.alpha = [self getAlphaValueForView:view];

UIView * superView = [currentView superview];
[currentView removeFromSuperview];

currentView = view;
[superView addSubview:currentView];

検索コンテンツ コントローラーをデフォルトのナビゲーション ルーチン (ナビゲーション コントローラー) で使用し始めると、空の検索結果テーブル ビューが点滅する問題が発生します。

そこで、この問題を解決するために、コンテンツ コントローラー (この場合はデフォルトの検索表示コントローラーがアクティブになっています) ではなく、空のコントローラーをナビゲーションに使用し始めました。そして、空のコントローラー ビューを検索ビューのサブビューとして使用しました。

つまり、ナビゲーションで UISearchDisplayController のコンテンツ ビュー コントローラーを使用しないでください。スタブ ビュー コントローラーを使用します。次に、そのビューを使用して、ビューをサブビューとして配置します。

私にとってはうまくいきました。

于 2012-12-16T21:16:03.570 に答える
-1

UISearchDisplayControllerたぶん、次の関数を実装する必要があります。

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
于 2011-03-03T04:00:41.837 に答える