Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initally hide searchbar in Navigation controller on iOS 13?

In iOS 13 the behavior has changed so that by default when Navigation controller appears the search bar is visible (when UISearchController is assigned to a navigationItem.searchController). Some system apps appear with the search bar hidden (you need to swipe down for it to appear), but I don't see any specific property that would allow this. How to achieve this - maybe there is some property or some method to do that?

like image 515
Ivan Ičin Avatar asked Aug 20 '19 21:08

Ivan Ičin


3 Answers

Via experimentation, I have discovered that if you delay assigning the search controller to the navigation item until viewWillLayoutSubviews or viewDidLayoutSubviews, the search controller starts out hidden, as desired. However, this if you do this on iOS 12 or earlier, the search controller will not be revealed when scrolling down.

I ended up doing the following with a messy version check, which is working for me:

override func viewDidLoad() {
    super.viewDidLoad()

    searchController = /* make search controller... */

    if #available(iOS 13, *) {
        // Attaching the search controller at this time on iOS 13 results in the
        // search bar being initially visible, so assign it later
    }
    else {
        navigationItem.searchController = searchController
    }
}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    navigationItem.searchController = searchController
}

like image 152
bunnyhero Avatar answered Nov 19 '22 05:11

bunnyhero


To start with a hidden searchBar, simply set the navigationItem.searchController property after your table view (or collection view) has been populated with data.

like image 24
Ely Avatar answered Nov 19 '22 05:11

Ely


Inspired by bunnyhero's answer I put the code responsible for setting the UISearchController in navigationItem inside the viewDidAppear method. Seems to be working every time for me on iOS 14/15

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if navigationItem.searchController == nil {
        navigationItem.searchController = searchController
    }
}

Edit: I was overly optimistic. On iOS 15.2 this method stopped working for me. What I did to fix it was to move the code after reloading my table/collection view.

like image 2
Adam Avatar answered Nov 19 '22 06:11

Adam