web-dev-qa-db-ja.com

UISearchControllerの検索バーをプログラムで表示する

注1:この質問は、更新するテーブルビューの外にUISearchControllerの検索バーを追加することに関するものであり、テーブルビューのヘッダーとしてではありません。

注2:試行錯誤の結果、解決策が見つかりました。以下の私の 回答 をご覧ください。

私はiOS開発に不慣れで、UISearchControllerクラスを操作するのに苦労しています。ビューコントローラーがあり、ビューコントローラーのビューでは、テーブルビューの上に検索バーを配置する予定です。検索バーをUISearchControllerにリンクさせたいのですが。 Interface BuilderにはUISearchControllerが付属していないため、プログラムでコントローラーを追加しています。 UISearchControllerをインスタンス化した後、プログラムで検索コントローラーの検索バーをビューに追加しようとしましたが、成功しませんでした。検索バーのフレームを設定して自動レイアウトの制約を設定しようとしましたが、どちらの方法も機能しませんでした(つまり、アプリを実行しても何も表示されません)。これが私が試した最新のコードです:

    let searchController = UISearchController(searchResultsController: nil)

    // Set the search bar's frame
    searchController.searchBar.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 50)

    // Constraint to pin the search bar to the top of the view
    let topConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0)
    searchController.searchBar.setTranslatesAutoresizingMaskIntoConstraints(false)

    self.view.addSubview(searchController.searchBar)

    self.view.addConstraint(topConstraint)

どんな助けでも大歓迎です!ありがとうございました!

EDIT:検索バーのフレームを設定するか、自動レイアウトの制約を与えるかのいずれかを使用すると(最初に試した両方の組み合わせではなく)、最初は機能しますが、検索バーをタップすると、Dwightが指摘したような問題が発生します。あなたが現在持っているものと比較するのに役立つ場合に備えて、これらのケースのコードを残しましたが、実用的な解決策については、以下の私の答えを参照してください。

自動レイアウト制約の使用:

    let searchController = UISearchController(searchResultsController: nil)

    let topConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: (statusBarHeight + navigationBarHeight!))
    let leftConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 0)
    let rightConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 0)
    let heightConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 44)
    searchController.searchBar.setTranslatesAutoresizingMaskIntoConstraints(false)

    searchController.searchBar.addConstraint(heightConstraint)

    self.view.addSubview(searchController.searchBar)

    self.view.addConstraints([topConstraint, leftConstraint, rightConstraint])

ビューコントローラがナビゲーションコントローラに埋め込まれているため、topConstraint定数をステータスバーの高さとナビゲーションバーの高さに設定しました。

フレームの調整:

    let searchController = UISearchController(searchResultsController: nil)

    searchController.searchBar.frame = CGRect(x: 0, y: (statusBarHeight + navigationBarHeight!), width: self.view.frame.size.width, height: 44)

    self.view.addSubview(searchController.searchBar)
8
kcstricks

さらに試行錯誤した結果、次のような解決策があります。

  1. Main.storyboardを開き、高さ44(UISearchBarのデフォルトの高さ)のUIViewとUITableViewをビューコントローラーに追加します。自動レイアウト制約を設定して、UIViewが両側と上部レイアウトガイドに固定され(上部レイアウトガイドを使用すると、View Controllerがナビゲーションコントローラーに埋め込まれているかどうかに関係なく機能するようになります)、テーブルビューがに固定されます。両側、下部のレイアウトガイド、およびその上部がUIViewの下部に固定されています。
  2. UIViewとUITableViewをViewController.SwiftのIBOutletsとして接続します。私のプロジェクトでは、それらをtopViewおよびtableViewと呼びました。
  3. ViewController.Swiftの上部で検索コントローラーを宣言します:var searchController: UISearchController!
  4. 次に、viewDidLoad()で、次のものが必要になります。

    // Initialize and set up the search controller
    self.searchController = UISearchController(searchResultsController: nil)
    self.searchController.searchResultsUpdater = self
    self.searchController.dimsBackgroundDuringPresentation = false // Optional
    self.searchController.searchBar.delegate = self
    
    // Add the search bar as a subview of the UIView you added above the table view
    self.topView.addSubview(self.searchController.searchBar)
    // Call sizeToFit() on the search bar so it fits nicely in the UIView
    self.searchController.searchBar.sizeToFit()
    // For some reason, the search bar will extend outside the view to the left after calling sizeToFit. This next line corrects this.
    self.searchController.searchBar.frame.size.width = self.view.frame.size.width
    

これはそれであるはずです!もちろん、ビューコントローラーをUITableViewDatasource、UITableViewDelegate、UISearchBarDelegate、UISearchControllerDelegate、UISearchResultsUpdatingにして、必要なすべてのデリゲートメソッドも処理する必要がありますが、検索バーに関する限り、これはうまくいきました。何か問題があればコメントしてください。

15
kcstricks