酢ろぐ!

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

UISearchBarをUINavigationBarに設定して、画面遷移すると画面がめり込む/画面に隙間が開いてしまう

iOS 13以降で、UISearchBarを navigationItem.titleView に設定している場合や、UISearchControllerを navigationItem.searchController に設定している場合、ドリルダウンで画面遷移して戻ってくると、画面がめり込んでしまう問題があります。これは UISearchBar の高さが 56ptに変更されたのが原因です。

発生している現象:UISearchBarをナビバーで表示すると画面がめり込む

UISearchBarを UINavigationBarのnavigationItem.titleView に設定しているケース。

searchBar = UISearchBar()
navigationItem.titleView = searchBar

UISearchControllerを UINavigationBarのnavigationItem.searchController に設定しているケース。

searchController = UISearchController(searchResultsController: nil)
navigationItem.searchController = searchController

どちらのケースでも下図のようにドリルダウンで画面遷移した詳細画面でナビバーとviewに謎の隙間が開いてしまいますし、この状態でリスト画面に戻った時にナビバーにviewがめり込んでしまいます。

f:id:ch3cooh393:20200419130829p:plain

謎の隙間というのは、ナビバーに設置した UISearchBar 分の高さであることがわかります。

解決方法:画面をめり込まないようにする

viewDidLoad()extendedLayoutIncludesOpaqueBars = true を実行する。

    override func viewDidLoad() {
        super.viewDidLoad()

        extendedLayoutIncludesOpaqueBars = true

        // ...
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        navigationController?.view.setNeedsLayout()
        navigationController?.view.layoutIfNeeded()
    }

下図のようにドリルダウンで画面遷移した詳細画面でナビバーとviewに謎の隙間が開かなくなりましたし、リスト画面に戻った時にもナビバーにviewがめり込まなくなりました。

f:id:ch3cooh393:20200419130836p:plain

参考