概要
よく UINavigationItem
と組み合わせて使われることが多い UISearchController
ですが、これを単体のViewControllerとして使えないか検証してみました。
結論
UISearchControllerはUINavigationItemと組み合わせてしか使わないこと推奨です。
通常の使い方
navigationItem.searchController
にUISearchControllerを割り当てるのが通常の使い方になるかと思います。
class ViewController: UIViewController {
var searchController: UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
searchController = UISearchController(searchResultsController: TableViewController())
searchController.showsSearchResultsController = true
navigationItem.searchController = searchController
}
}
独自のボタンでpresent
これを、Searchバーではなく、こちらで用意したボタンなどのアクションきっかけで表示したいと考えました。
present(searchController, animated: true)
このコードで表示をさせてみると、微妙に検索結果の上部に隙間が空いた検索表示になりました。

独自のボタンでpush
presentがダメなら、navigationのpushではどうだろうか。
navigationController?.pushViewController(searchController, animated: true)
このコードで表示をさせてみると、検索結果表示部だけ見えて、検索窓が見えない形になっています。

UISearchControllerのSearch Barを配置する
ドキュメントをよくみてみます。
On iOS, incorporate the search controller’s
searchBar
into your own view controller’s interface. Display your view controller in whatever way is appropriate for your app. See Displaying Searchable Content by Using a Search Controller and Using Suggested Searches with a Search Controller to learn how to implement a search controller in your app.
なるほど、searchBarをビューコントローラーに組み込む、とありますね。
今までのパターンはそのままUISearchControllerを無理矢理表示しようとしていたので、きちんとドキュメントに沿って、searchBarを配置してみましょう。
class ViewController: UIViewController {
var searchController: UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
searchController = UISearchController(searchResultsController: TableViewController())
searchController.showsSearchResultsController = true
let searchBar = searchController.searchBar
view.addSubview(searchBar)
searchBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
searchBar.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
searchBar.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
searchBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
])
}
}
そうすると、検索バーをタップした瞬間、サーチバーが明後日の方向へ飛んで行きました。
まとめ
UISearchControllerはUINavigationItemと組み合わせて使われることしか想定されていないようです。
この場合、UIは検索窓の表示で画面が占有されてしまうので、例えば虫眼鏡ボタンを置いて、それを押下して検索させたい場合は自分でUISearchBarなどを組み合わせてUIを作成するのがよさそうです。
おまけ (tvOS)
tvOSの場合、そもそもUINavigationItemにsearchControllerのプロパティがありません。
UISearchContainerViewController
と組み合わせて表示する形になります。
let searchController = UISearchController(searchResultsController: TableViewController())
let searchContainerViewController = UISearchContainerViewController(searchController: searchController)
present(searchContainerViewController, animated: true, completion: nil)