UISearchDisplayController で用意される UITableView を扱う上での注意点

2010年7月26日月曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

以前、UISearchDisplayController についてのまとめを書いた。
[参考] Cocoaの日々: UISearchDisplayController と NSFetchedResultContoller を組み合わせる (3) 考察

さらに分かったことがあるので追記する。


[1] 検索毎に新規に UISearchResultsTableView が作り直される


-[UISearchDisplayControllerDelegate searchDisplayController:willShowSearchResultsTableView:] において引数で渡される UITableView をデバッグ出力したところ、検索毎に異なることがわかった。
[44712:207] <UISearchResultsTableView: 0x6044c00; ...
[44712:207] <UISearchResultsTableView: 0x6099200; ...
[44712:207] <UISearchResultsTableView: 0x6828e00; ...

つまり検索毎に作り直されている。通常表示(非検索時)用の UITableView の属性はコピーされないようなので、必要ならこのデリゲートメソッドで毎回属性の設定を行ってやる。

[例]
- (void)searchDisplayController:(UISearchDisplayController *)controller
  willShowSearchResultsTableView:(UITableView *)tableView
{
 tableView.backgroundColor = [UIColor clearColor];
 tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}



[2] UISearchResultsTableView は UITableView の上に重なって表示される


UISearchResultsTableView は UITableView の上に重なって表示される。


この為、背景色を透明にしている場合は検索結果表示の下に通常表示のビューが重なって見えてしまう。

これでは困るので検索時には通常表示のビューを隠す必要がある。ただ単純に hidden=YES とすると、UISearchBarまでが非表示なってしまう。これは UISearchBar が通常表示ビュー UITableView のヘッダに描かれているため。ヘッダ以外の部分だけを隠せないものだろうか。

試しに UITableView の subviews を表示してみた。
[44878:207] (
    "<UITableViewCell: 0x68a1e80; frame = (0 404; 320 72); ...
    "<UITableViewCell: 0x689cc90; frame = (0 332; 320 72); ...
    "<UITableViewCell: 0x6897ab0; frame = (0 260; 320 72); ...
    "<UITableViewCell: 0x6892800; frame = (0 188; 320 72); ...
    "<UITableViewCell: 0x688d410; frame = (0 116; 320 72); ...
    "<UITableViewCell: 0x6876600; frame = (0 44; 320 72); ...
    "<UISearchBar: 0x6862260; frame = (0 0; 320 44); ...
    "<UIImageView: 0x6863840; frame = (0 0; 7 7); ...
なるほど。ヘッダと同じレベルで表示されているセルが1つずつ全部乗っているのか。
とすると、これらのセルを全部非表示にしてやる必要がありそうだ。ただそれをやると内部構造に依存するため今後の iOSのバージョンアップで非互換になる可能性がある。

色々考えたが、他に方法も無い(*1)のと恐らくこの構造が大きく変わることは無いと踏んで今回はセルを全部非表示にしてみる。
(*1) 今回背景色を透明にしているのは、ビュー階層の一番下に背景画像を表示しているからで、別の方法でこれが実現できれば内部構造に依存したコードを書く必要はなくなる。


まず現在表示されているセルの表示制御を行うメソッドを1つ用意する。
- (void)setDisplayedCellsHidden:(BOOL)hidden
{
 for (UIView* view in self.tableView.subviews) {
  if ([view isKindOfClass:[UITableViewCell class]]) {
   view.hidden = hidden;
  }
 }
}

これを検索開始と、検索終了のタイミングで呼び出す。

// 検索開始
- (void)searchDisplayController:(UISearchDisplayController *)controller
  willShowSearchResultsTableView:(UITableView *)tableView
{
  :
 [self setDisplayedCellsHidden:YES];
}

// 検索終了
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
  :
 [self setDisplayedCellsHidden:NO];
}

Responses

Leave a Response

人気の投稿(過去 30日間)