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?
-
Navigation controllers don't have search bars by default so please update your question with details about what you are doing to get a search bar in place.rmaddy– rmaddy2019-08-20 21:10:56 +00:00Commented Aug 20, 2019 at 21:10
-
@rmaddy I will but just wandering if you really have no idea what I am doing as showing search bar in navigation controller is a standard procedure since iOS 11.SOuser– SOuser2019-08-20 21:39:56 +00:00Commented Aug 20, 2019 at 21:39
-
There are different solutions so it is important for you to be clear on what exactly it is that you are doing. Your edit is far from enough detail.rmaddy– rmaddy2019-08-20 22:24:33 +00:00Commented Aug 20, 2019 at 22:24
-
@rmaddy as some people (possibly you) downvote, please answer what you are missing. Did you try to reproduce the problem with the description above. I can, and I don't see how implementation of searchbar controller would influence this as even the simplest one works.SOuser– SOuser2019-08-21 09:59:50 +00:00Commented Aug 21, 2019 at 9:59
-
9This question seems clear to me. Navigation Items with search controllers assigned (thus with a search bar) behave differently in iOS 13 - they are visible on load. The obvious ideas (setting a content offset of the table, or programatically scrolling the table to a the first row) don't work.Andrew Bennet– Andrew Bennet2019-09-04 22:17:40 +00:00Commented Sep 4, 2019 at 22:17
8 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
}
7 Comments
viewWillLayoutSubviews or viewDidLayoutSubviews, try doing it in viewDidAppear instead. That worked for me!To start with a hidden searchBar, simply set the navigationItem.searchController property after your table view (or collection view) has been populated with data.
1 Comment
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.
1 Comment
This is what works for me. I have a UISegmentedControl that reloads the tableView when filter changes.
With FRC:
guard let count = try? fetchedResultsController.managedObjectContext.count(for: request) else { return }
called after tableView.reloadData()
navigationItem.searchController = count > 20 ? searchController : nil
Comments
I find this works:
self.searchController.searchBar.hidden = YES;
You will need to unhide at the appropriate time.
1 Comment
I managed to make this work by setting isTransculent false on the navigationBar and having initial data on UITableView or UICollectionView. If you have 0 cells initially and trigger reloadData after some time (maybe a network call), SearchBar is visible initially. So have a dummy cell or something similar initially and load the data later, if that's the case for you.
navigationController?.navigationBar.isTranslucent = false
Comments
Swift 5.2 & iOS 13.3.1:-
Try like this. It works fine
navigationItem.hidesSearchBarWhenScrolling = false