質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2547閲覧

[swift] searchBarに何も入力されていない時tableViewを消したい

Tajiko

総合スコア12

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/05/09 06:45

編集2019/05/09 13:26

前提・実現したいこと

検索された場所を基準として特定の施設を検索できるiPhone用アプリを作っています。
下記のiOSのマップように、searchbarをタップし地名などを入れると検索候補がtableViewで表示され、
searchBarがキャンセルボタン押下で空欄になったりキーボードで文字を削除して空欄になったりしたときにはtableViewを削除したいのですが、うまく行きません。
キャンセルボタンをおしたとき、一度searchBarに入力した単語を削除したときにtableViewを消すにはどうしたら良いのでしょうか。

![イメージ説明]

発生している問題・エラーメッセージ

現状はこのように、searchBarが空欄でもtableViewが残ってしまいます。
イメージ説明

該当のソースコード

swift

1import UIKit 2import MapKit 3 4var tableView: UITableView! 5 6class ViewController: UIViewController, UISearchBarDelegate, MKMapViewDelegate, MKLocalSearchCompleterDelegate { 7 8 @IBOutlet weak var mapView: MKMapView! 9 @IBOutlet weak var searchBar: UISearchBar! 10 11 var locationManager: CLLocationManager? 12 var annotationArray: [CustomAnnotation] = [] 13 var completer = MKLocalSearchCompleter() 14 15 override func viewDidLoad() { 16 super.viewDidLoad() 17 18 self.mapView.delegate = self 19 searchBar.delegate = self 20 21 completer.delegate = self 22 completer.filterType = .locationsOnly 23 } 24 25 26 //キーボードの検索ボタンクタップ時に呼ばれるメソッド 27 func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 28 //キーボードを閉じる 29 searchBar.resignFirstResponder() 30 //キャンセルボタンの表示 31 searchBar.setShowsCancelButton(false, animated: true) 32 33 //入力された文字を取り出す 34 if let searchKey = searchBar.text { 35 //入力された文字をデバッグに表示 36 print(searchKey) 37 38 //CLGeocoderインスタンスを取得 39 let geocoder = CLGeocoder() 40 41 //入力された文字から位置情報を取得しマップにアノテーションを表示する処理。省略。 42 43 //データベースを検索するメソッドを行う 44 self.searchDB(keyword: searchKey) 45 } 46 47 48 //jsonの中身を受け取るデータ構造 49 struct Databaser: Codable { 50 // 省略 51 } 52 53 //データベースを検索するメソッド 54 func searchDB (keyword: String) { 55 //省略 56 } 57 58 //アノテーションビューを返すメソッド 59 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 60 //省略 61 } 62} 63 64extension ViewController: UITableViewDelegate, UITableViewDataSource { 65 66 func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 67 68 let tableView = UITableView(frame: CGRect(x: 32, y: 120, width: view.frame.width - 100, height: view.frame.height / 3)) 69 tableView.register(UITableViewCell.self, forCellReuseIdentifier: "data") 70 tableView.separatorStyle = .none 71 tableView.delegate = self 72 tableView.dataSource = self 73 tableView.tableFooterView = UIView() 74 75 if searchBar.text != "" { 76 self.view.addSubview(tableView) 77 } else { 78 tableView.removeFromSuperview() 79 } 80 81 searchBar.setShowsCancelButton(true, animated: true) 82 } 83 84 //入力に変更があった際に呼び出されるメソッド. 85 func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { 86 guard let text = searchBar.text else { return false } 87 completer.queryFragment = text 88 return true 89 } 90 91 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 92 93 tableView.estimatedRowHeight = 20 94 return UITableView.automaticDimension 95 } 96 97 //tableViewが何行か決めるメソッド 98 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 99 return completer.results.count 100 } 101 102 //tableViewのセルの内容を決めるメソッド 103 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 104 let identifier = "Cell" 105 var cell = tableView.dequeueReusableCell(withIdentifier: identifier) 106 107 if (cell == nil) { 108 cell = UITableViewCell(style: .default, reuseIdentifier: identifier) 109 } 110 111 cell?.textLabel?.text = completer.results[indexPath.row].title 112 return cell! 113 } 114 115 // セルを選択したときのメソッド 116 private func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 117 118 } 119 120 // キャンセルボタンタップ時に呼び出されるメソッド. 121 func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { 122 searchBar.resignFirstResponder() 123 searchBar.setShowsCancelButton(false, animated: true) 124 searchBar.removeFromSuperview() 125 } 126}

swift

1修正後 2import UIKit 3import MapKit 4 5class ViewController: UIViewController, UISearchBarDelegate, MKMapViewDelegate, UITableViewDelegate, UITableViewDataSource,MKLocalSearchCompleterDelegate { 6 7 @IBOutlet weak var mapView: MKMapView! 8 @IBOutlet weak var searchBar: UISearchBar! 9 @IBOutlet weak var tableView: UITableView! 10 var locationManager: CLLocationManager? 11 var annotationArray: [CustomAnnotation] = [] 12 var completer = MKLocalSearchCompleter() 13 14 override func viewDidLoad() { 15 super.viewDidLoad() 16 //省略 17 18 searchBar.delegate = self 19 tableView.delegate = self 20 tableView.dataSource = self 21 tableView.isHidden = true 22 completer.delegate = self 23 completer.filterType = .locationsOnly 24 } 25 26 27 28 func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 29 30 if searchBar.text != "" { 31 tableView.isHidden = false 32 } else { 33 tableView.isHidden = true 34 } 35 36 searchBar.setShowsCancelButton(true, animated: true) 37 } 38 39 func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 40 //キーボードを閉じる 41 searchBar.resignFirstResponder() 42 //キャンセルボタンの表示 43 searchBar.setShowsCancelButton(false, animated: true) 44 45 //入力された文字を取り出す 46 if let searchKey = searchBar.text { 47 //入力された文字をデバッグに表示 48 print(searchKey) 49 50 //CLGeocoderインスタンスを取得 51 let geocoder = CLGeocoder() 52 //入力された文字列から位置情報を取得してアノテーションで表示する処理。省略。 53 } 54 } 55 56 //入力に変更があった際に呼び出されるメソッド. 57 func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { 58 guard let text = searchBar.text else { return false } 59 completer.queryFragment = text 60 return true 61 } 62 63 // キャンセルボタンタップ時に呼び出されるメソッド. 64 func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { 65 searchBar.setShowsCancelButton(false, animated: true) 66 tableView.isHidden = true 67 } 68 69 //tableViewが何行か決めるメソッド 70 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 71 return completer.results.count 72 } 73 74 //セルの内容を設定するメソッド 75 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 76 let identifier = "Cell" 77 var cell = tableView.dequeueReusableCell(withIdentifier: identifier) 78 79 if (cell == nil) { 80 cell = UITableViewCell(style: .default, reuseIdentifier: identifier) 81 } 82 83 cell?.textLabel?.text = completer.results[indexPath.row].title 84 return cell! 85 } 86 87 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 88 tableView.estimatedRowHeight = 20 89 return UITableView.automaticDimension 90 } 91 92 // セルを選択したときのメソッド 93 private func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 94 95 } 96 97} 98 99

試したこと

searchBarに文字が何かしら文字が入力されている時はaddSubviewでtableViewを表示し、
何も入力されていない時はremoveFromSuperview()すればいいのかと思いifで分岐してみましたがうまくいきませんでした。

補足情報(FW/ツールのバージョンなど)

こちらを参考にここまで作りました。
https://github.com/hanawat/local-search-completer

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

テーブルそのものを非表示にしたいならtableView.isHhidden = true
セルを非表示(というかクリア)したいなら、resultsを空っぽにしてテーブルをリロードして下さい。

投稿2019/05/09 07:02

編集2019/05/09 07:04
fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tajiko

2019/05/09 08:09

さっそくご回答いただきありがとうございます。 お教えいただいた通りキャンセルボタンを押した時にテーブルを消したいので searchBarCancelButtonClickedメソッドの中で tableView.isHidden = true としたのですがエラーが出てしまいました。 エラー: Ambiguous reference to member 'tableView(_:heightForRowAt:)' エラーの解釈は、 searchBarに何かしら単語が入力されてからtableVeiwを作ればいいと考えていたため tableViewをインスタンス化するのを func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) の中に書いてしまっています。なのでtableViewという変数がsearchBarCancelButtonClickedでは認識できない、という解釈で合っていますいますでしょうか。 また、上記の解釈で合っている場合は、tableViewを生成する記述を他の場所に書く(例えば、他のクラスに書くなど?)した方がよいということでしょうか。
fuzzball

2019/05/09 08:45 編集

認識していないのではなく、グローバル変数のtableViewを参照しようとしてエラーになっているようですね。(理由は分かりません) ひとまず現状でおかしな点を修正しましょう。 ・グローバル変数のtableViewをインスタンス変数に変更する。 ・テーブルビューの生成時/参照時はそのインスタンス変数を使うようにする。 ・テーブルビューの生成はサーチバーの生成時に。 ・searchBar(_:textDidChange:)の中では、表示/非表示の切り替えだけおこなう。 ・searchBarCancelButtonClicked(_:) は、そのExtensionに入れるべきではない。(これはオマケです) ちゃんとソース全体を見ていないので、細かいところはご自分で適宜修正をお願いします。
Tajiko

2019/05/09 13:28

ありがとうございます。 グローバル変数をやめ、storyboard上にTableViewを配置し、isHiddenで表示非表示をそれぞれのメソッドで設定しました。また、ectensionをやめ普通にViewControllerの中に全てのメソッドを入れました。そうしましたらtableViewについてはサーチバーに文字が入力されている時だけ表示され、文字が何もない時はひい表示にすることができました。ありがとうございます。 しかし、今度はtableViewに検索候補地が表示されなくなってしまいました。 重ね重ね大変申し訳ないのですが、修正後のコードを本文に追加いたしましたのでもう一度ご指導いただけないでしょうか。よろしくお願いいたします。
Tajiko

2019/05/09 13:38

申し訳ございません。22:28のコメントは私の凡ミスにより発生しているものでした。 無事解決いたしました。 fuzzball様、いつもありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問