酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

UISearchBarをタップしたらテキストを入力していなくても searchResultsControllerの背景を表示したい (UISearchController使用時)

UISearchControllerを使うと、入力したテキストをベースにして検索結果を表示させられます。OSとして標準的な検索手段をユーザーに提供することができます。

f:id:ch3cooh393:20200407184209p:plain

ただ、検索結果の絞り込みに UISearchController を使っている例は多いのですが、実際には navigationItem.titleView = searchController.searchBar のように検索枠だけ使っているケースや、UISearchController(searchResultsController: nil)として、元のViewController側で検索結果を表示しているケースがほとんどです。

searchResultsController を指定して使っているケースはあまり紹介ないように思いました。そのなかで、さらにニッチな使い方をするとなると実現方法が分からず困ってしまいました。

本記事では、UISearchBar部分がタップされたら テキストを入力していなくても searchResultsController を表示する方法を紹介します。

前提

UISearchControllerに検索結果を表示させるためのViewContoroller searchResultsController をすると、検索結果を表示する際に searchResultsController で処理をおこなうことが可能です。

let resultController = SearchResultViewController()
searchController = UISearchController(searchResultsController: resultController)
searchController.delegate = resultController

// 設定は省略...

navigationItem.searchController = searchController

UISearchControllerの組み込み方についてはここでは割愛します。既存の記事をご参照ください。

問題点

UISearchBarにテキストを入力すると、そこで初めて searchResultViewController の背景が表示されます。これはドキュメントに書かれた挙動です。

f:id:ch3cooh393:20200407183323p:plain

僕は UISearchBarにフォーカスが当たった時点で、 searchResultViewController の背景が表示されて欲しかったので試行錯誤することになってしまいました。

解決方法

navigationItem.searchController = searchController をした時点で、searchResultViewControllerが追加されていることに気付き、UISearchBarにフォーカスが当たったイベント willPresentSearchController(_:) のなかで view.isHidden = falseをすることで、検索結果画面が表示することができました。

    // MARK: - UISearchControllerDelegate

    func willPresentSearchController(_ searchController: UISearchController) {
        DispatchQueue.main.async { [weak self] in
            self?.view.isHidden = false
        }
    }
    
    func didPresentSearchController(_ searchController: UISearchController) {
        view.isHidden = false
    }

UISearchBarにフォーカスが当たった時点で検索結果画面を表示させている動画です。

f:id:ch3cooh393:20200407181004g:plain