UISearchController clears UISearchBar text when dismissed
Asked Answered
F

3

8

In viewDidLoad of my custom subclass of UITableViewController, I've set navigationItem.titleView to the searchBar of a UISearchController, which I initialized with nil for searchResultsController.

When I tap into the search bar, enter text, and tap on the dimmed underlying content, then the UISearchController gets deactivated (as expected) and the search text I entered gets cleared (unexpectedly).

The search text is also cleared (also unexpectedly) when I explicitly (programmatically) set the search controller to be inactive. To get around that, I store the search text before and set it back after dismissing the search controller. Although hacky, it works.

let searchText = searchBar.text // #hack
searchController.isActive = false
searchBar.text = searchText     // #hack

For when the search controller is automatically dismissed, I tried something similar using the UISearchControllerDelegate methods, i.e., storing the search text in willDismissSearchController(_:) and setting it back in didDismissSearchController(_:). But, this solution still shows the search text getting cleared and then getting set back to what it was before.

How do I seamlessly keep the search bar text as is when the search controller is dismissed automatically?

Formulate answered 31/12, 2016 at 1:49 Comment(7)
uisearchbar delegate.Continual
How could the search bar's delegate keep the search controller from clearing its text?Formulate
uisearchbar delegate method i have demo but now i m not near computerContinual
Maybe you should create a custom search controller and add a custom searchbar property to it. Then declare the custom delegate for the search controller and searchbar.Badillo
subclass UISearchBar ?Fox
Thank you all for your suggestions, but please provide more explanation. I tried subclassing UISearchController & UISearchBar, but neither willSet or didSet of UISearchController.isActive or set of UISearchBar.text seem to get called when the search controller is dismissed automatically.Formulate
OK, I got it! Thanks. :-)Formulate
W
6

For explicitly (programmatically) dismissing the search controller, UISearchController is a view controller, so you can just call dismiss(animated:completion:) on it rather than setting isActive = false and resetting the search text:

searchController.dismiss(animated: true)

The search bar text will still persist in the search bar after dismissing.

Windowshop answered 13/12, 2018 at 20:32 Comment(1)
this is a gem, I've been struggling with this problem and hacking around using didDismissSearchController function but was annoyed by the lag, this solved everything and also avoids tons of storing/controlling of the current state!Gayle
F
1

In searchBarTextDidEndEditing(_:), set searchBar.text back to what it was before.

See: UISearchBar : How to prevent Cancel Button from clearing text?

Formulate answered 31/12, 2016 at 22:20 Comment(0)
S
0

I solved this problem by comparing one of Apple's sample projects to my own. As it turns out, you want to show your results in a separate table view controller than in the unfiltered data. Before you initialize your UISearchController, set up a separate TableViewController, and when you initialize your UISearchController, send the separate table view controller as the searchResultsController: argument.

searchController = UISearchController(searchResultsController: 
                       self.searchResultsController)

Then in the updateSearchResults(for:) method I called self.searchResultsController.tableView.reloadData() after filtering my results.

This separate view controller will make the search controller behave in the way you would expect. I know that it's not by far a simple solution. In the interest of displaying search results in a way that makes it feel like they are being presented in the same table view as the unfiltered data, I'm not sure why Apple designed it this way but that's how it goes.

Sugden answered 19/2, 2020 at 22:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.