■画面内での検索機能の実装
iPhoneの小さな画面で演劇感想文リンクの膨大な公演情報を効率よく見てもらうためには検索機能は必須になると考えています。
色々な検索機能を実装していきたいと思っているのですが、とりあえず一番簡単なTableViewに表示されている公演の一覧から、公演名にもとづいて検索する機能を実装することにします。
以下の方針で実装。
- 検索バーを画面上に表示。(UISearchBarで実装)
- 入力された文字列に応じて、配列として保有している配列を絞り込む(filter)
- 絞りこまれた配列に応じて、TableViewを再表示。(datareroad)
■UISearchBarの実装
ネットを検索したところ、UISearchBarという部品によって検索窓の実装が行えるようです。検索窓を実装し、画面上に表示するコードを作成しました。検索窓の実装の為に、画面のクラスにprotocol[UISearchBarDelegate]を加えます。
class 劇団画面型: 共通対象画面型,UISearchBarDelegate{ 〜 中略 〜 //検索文字列入力領域 lazy var 検索窓:UISearchBar=self.検索窓生成()
検索窓の生成は、以下のように各プロパティを実装します。
private func 検索窓生成()->UISearchBar{ let 窓:UISearchBar=UISearchBar() 窓.frame=CGRectMake(0,0,400,80) 窓.delegate=self //窓.text="入力ワード" //窓.prompt="サーチバーのタイトル" 窓.placeholder="公演名(一部でも可)" 窓.showsCancelButton=true 窓.showsBookmarkButton=false 窓.showsSearchResultsButton=true 窓.keyboardType=UIKeyboardType.Default 窓.searchBarStyle=UISearchBarStyle.Default 窓.barStyle=UIBarStyle.Default 窓.tintColor=UIColor.redColor() return 窓 }
サイズは、別途他の要素との関係で設定するので、適当です。サーチバーのタイトルや、デフォルト表示はしないので、.text ,.promptのプロパティは未設定としました。他のプロパティは基本的にはデフォルトで設定。
検索窓の配置は、ラベルとTableViewの間に配置するので、そんな感じで。
private func 検索窓配置(){ let 検索窓頂点=値ラベル集[値ラベル集.count-1].frame.origin.y+値ラベル集[値ラベル集.count-1].frame.size.height 検索窓.frame.size=CGSizeMake(self.frame.size.width-20,40) 検索窓.frame.origin.y=検索窓頂点+10 検索窓.frame.origin.x=10 検索窓.backgroundColor=UIColor(white:0.9,alpha:1.0) }
■配列の絞り込み
これまで、あくまで画面設計に注力してきたこともあり、データの取り扱いはかなりいい加減に作ってきました。このアプリを作成するためには、データの取り扱いと配列の取り扱いはかなり勉強しなければならないのですが、まだまだです。
今回は、画面に設定されている配列から、検索文字列での検索をします。
配列の絞り込みには、filter関数を利用しました。
公演クラスの題名でフィルタリングします。
//when search click func searchBarSearchButtonClicked(searchBar: UISearchBar) { 検索実行() 検索窓.text = "" //self.view.endEditing(true) } private func 検索実行(){ let 検索文字列=検索窓.text let 絞込後公演集=公演集.filter({$0.題名.containsString(検索文字列!)}) //self.公演集=絞込後公演集 self.公演集画面.公演集=絞込後公演集 self.公演集画面.reloadData() }
フィルタリングをしたデータを絞込後の公演集として、公演集画面にセット。
公演集画面をリロード(reloadData())処理を施すことで、絞りこまれたデータのみが表示されました。
なお、検索前の表示したリスト(この場合は、公演の一覧である「公演集」)は、直接更新せず、別に残しておく必要があります。
そうすれば、Cancelボタン押下時には、以下のように簡単に元の状態に戻すことができます。
//when cancel click func searchBarCancelButtonClicked(searchBar: UISearchBar) { //myLabel.text = "" 検索窓.text = "" 検索取消() } private func 検索取消(){ self.公演集画面.公演集=self.公演集 self.公演集画面.reloadData() }