Im running into a problem when I preform a search, I can't get the search bar to reset from it's focused state (The background view is dimmed and the cancel button is still in the search bar. I want to clear the search bar and NOT have the background dimmed).
The view controller has the following (in the view did load):
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.delegate = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.placeholder = "Search here"
searchController.searchBar.searchBarStyle = .minimal
self.navigationItem.searchController = searchController
When I tap search, I get have the following:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.endEditing(true)
searchBar.resignFirstResponder()
searchBar.text = ""
self.navigationItem.searchController?.resignFirstResponder()
}
The searchBar.endEditing(true) doesn't seem to be doing anything. Nor the resignFirstResponder. The background of the view is still dimmed.
For reference, the view controller is embedded in a nav controller, which in part a tab bar view controller (if that matters). And after the search is made, I push another view controller on the stack (hence why I want to clear the search bar and reset it's state when the view controller is shown again).
I've added some pictures to show the problem visually. The second photo is what Im left with after search is pressed when I want to to reset and look like the first photo.
self.navigationItem.searchController?.isActive = false is apparently what I'm looking for
Related
I have a view controller in which I dynamically create a UISearchController and assign it to self.navigationItem.searchController.
class MyViewController: UIViewController, UISearchBarDelegate {
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.searchController = searchController
searchController.searchBar.delegate = self
// launch the app directly into this search text box
searchController.searchBar.becomeFirstResponder()
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
// I tried this
searchBar.resignFirstResponder()
// and this
searchBar.endEditing(true)
// and finally this
return true
}
}
The keyboard hides away when the user touches anywhere outside the searchbar and the screen goes back to its brightness. That is the expected behavior.
However, when the user taps the [Search] button within the on-screen-keyboard, the keyboard goes away, but the screen is kept dim. None of the sub-views are useable, except if the user taps the search bar again, then the keyboard comes back.
So in short, the only way for the user to continue using the view controller, is not to hit the [search] button, which is counter-intuitive.
am I missing something?
In viewDidLoad(), add the following line:
searchController.obscuresBackgroundDuringPresentation = false
From the documentation: If you use the same view controller to display the searchable content and search results, it is recommended that you set this property to false. The default value of this property is true.
I'm using a search controller in order to implement a search section in an iOS app. I'm using iOS 11 and xCode 10.
My scene is a Table View Controller. I have included a search bar programmatically with the following code:
override func viewDidLoad() {
super.viewDidLoad()
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.delegate = self
definesPresentationContext = true
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
}
I have also included a UISearchBar delegate extension:
extension SearchTableViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
tableView.reloadData()
episodeResultsArray = []
let searchTerm = searchBar.text!
let escapedSearchTerm = searchTerm.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
performSearch(forTerm: escapedSearchTerm)
}
}
The performSearch function connects to a database via AlamoFire and returns the results which are then listed in the Table View.
When I run the app, the table appears empty (as it should be initially). When I click on the search bar, it enters the editing state (the navigation bar collapses, the search bar sticks to the top, a Cancel button appears, and a translucent grey box covers the rest of the screen.
When I search for something, the results are succesfully listed in the table. However, even though the results are visible, I still remain in the editing state for the search bar. I need to click on the translucent box to exit the editing state and only then I am able to scroll through the results.
How can I exit the editing state after I click on Search so I'm able to scroll through the table as soon as I get the results?
I tried using searchBar.resignFirstResponder() but this only dismisses the keyboard. I also tried
searchBar.endEditing(true)
but even though the search bar loses focus, I'm still in the editing state.
Just to clarify, I need for this to work as a search from scratch, not as a filter, meaning not just showing a subset of results as I type.
Found the answer. The solution is to add
searchController.isActive = false
Hello I have a searchController which disappears on click on one of the search items that appeared before the new view displays. What I would like is for the search controller to stay active so when the user goes back to the view they still see the list of results. currently I display the search controller with a present function. Any ideas how to stop this from leaving the screen? Thank you in advance!!
MainViewController:
func searchButtonClicked(){
self.searchController?.isActive = true
self.searchController?.searchBar.becomeFirstResponder()
if let controller = self.searchController {
present(controller, animated: true, completion: nil)
}
}
func searchItemClicked(){
self.searchController?.isActive = false
//set up detail controller and push
let vc : detailViewController =self.storyboard?.instantiateViewController(withIdentifier:"DetailViewController")
self.navigationController?.pushViewController(vc, animated: true)
}
func setupSearch(){
self.searchController = UISearchController.init(searchResultsController: searchResultsCustomController)
self.searchController?.obscuresBackgroundDuringPresentation = true
self.searchController?.searchBar.delegate = self
self.searchController?.searchBar.showsCancelButton = true
self.searchController?.searchBar.placeholder = "Search for people or places"
}
EDIT:
To add more information regarding this error. The navigation bar has a search button which the user clicks to do a search. From here the searchController is started and a search bar appears. Upon entering credentials for the search the table view appears with results. If the user clicks on one of this results, the table view and the search bar disappear by going up as if I pressed the cancel button, and then the screen is pushed to the detail view controller.
For anyone running into this issue all you have to do is add the following line of code on your viewdidload function:
self.definesPresentationContext = true
In my app, I used to have a search bar in the header view of my table view. However, I have added a search bar button item, and when a user taps it, I want a search bar to animate across the navigation bar, and the user should be able to search. This is kind of like the search bar in the Twitter iOS app. here is the code for my UISearchController:
self.searchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.hidesNavigationBarDuringPresentation = true
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
//self.tableView.tableHeaderView = controller.searchBar
self.definesPresentationContext = true
controller.searchBar.returnKeyType = .Search
controller.searchBar.delegate = self
return controller
})()
Here is how my UINavigationBar looks like right now:
How would I go about doing this?
You're almost there. You need to do four things:
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.titleView = searchController.searchBar
hide all the current UIBarButtonItems you have in the navigation bar
searchController.searchBar.becomesFirstResponder()
That is, you setup your UISearchController so it doesn't hide the navigation bar, as the UISearchBar is gonna be displayed there.
Then, when your IBAction runs, you do something like:
navigationItem.hidesBackButton = true
navigationItem.titleView = searchController.searchBar
navigationItem.rightBarButtonItem = nil
searchController.searchBar.becomeFirstResponder()
That guarantees the UISearchBar will use the entire UINavigationBar when it becomes the first responder. You also get the UISearchBar animation, which does a good job in hiding the unanimated removal of the UIBarButtonItems.
You will need to implement the UISearchBarDelegate (or if you prefer UISearchControllerDelegate) to restore the original navigation bar state once the user is done with the search.
One very important detail is that in order for your UISearchBar to be editable in the titleView, no other view controller can be set with definesPresentationContext = true at the time yours is pushed.
I AM NOT USING STORYBOARD SEGUES.
When I use UISearchController to have a search bar at the top of my table view, I get extremely strange behavior. Is there documentation on how I'm supposed to handle the search bar when a view dismisses? When I switch to a new view controller via an animation or push one on a nav stack, the bar is stuck in its spot until I hit the "Cancel" button.
See a video of what's happening in this short clip:
https://www.youtube.com/watch?v=6G7xFMENm_o&feature=youtu.be
This is the code, in the view controller, that sets up search bar:
var s: UISearchController!
private func configureSearching() {
s = UISearchController(searchResultsController: nil)
s.searchResultsUpdater = self
s.dimsBackgroundDuringPresentation = false
s.searchBar.searchBarStyle = .Minimal
s.hidesNavigationBarDuringPresentation = false
tableView.tableHeaderView = s.searchBar
s.searchBar.sizeToFit()
}
you should add the following line in viewDidLoad
self.definesPresentationContext = true