UISearchBar in UISearchController Does Not Disappear - ios

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

Related

Swift UISeachController add nav bar on selection

I currently have my UISearchController set up so it is presented over the nav bar once the search icon is clicked.
var searchController: UISearchController!
#IBAction func searchMe(sender: UIBarButtonItem) {
// Create the search results view controller and use it for the `UISearchController`.
let searchResultsController = storyboard!.instantiateViewControllerWithIdentifier(SearchResultsViewController.StoryboardConstants.identifier) as! SearchResultsViewController
// Create the search controller and make it perform the results updating.
searchController = UISearchController(searchResultsController: searchResultsController)
searchController.searchResultsUpdater = searchResultsController
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.tintColor = Colors.blue
searchController.searchBar.barTintColor = UIColor.whiteColor()
// Present the view controller.
presentViewController(searchController, animated: true, completion: nil)
}
I am using a different searchResultsController than the current table view to display results. The problem is that when a cell is selected in the searchResultsController a segue is performed to a new view controller (the users profile) and there is no navigation bar.
I need a back button to appear to take the user back to the searchResultsController. I have tried a bunch of different segues, setting the nav bars on the storyboard but nothing seems to work. My initial thought was to make this line of code:
searchController = UISearchController(searchResultsController: searchResultsController)
point to a nav controller with searchResultsController as its root view controller but I had no luck. Any help is great! Thank you!

Add UISearchBar to UINavigationBar with UIBarButtonItem

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.

Disappearing UISearchController in a TableViewController that is in a UINavigationController

I have made a UITableView Controller with a UISearchBar as the Table's header.
I have then embedded this View Controller into a UINavigationController, as the root view controller.
Now, when I tap on the Search Bar, the SearchBar seems to disappears and displays a white screen. The keyboard appears, but there is no Search Bar.
The Table View can scroll, but the search bar has simply vanished.
When I implement this UITableViewController without the Navigation Controller, it works perfectly. But something about the Navigation Controller is borking everything up.
I've had the same issue that was sometimes happening, especially with table view of small number of rows (less than 50).
It appears the searchBar is removed from the view hierarchy, precisely from the container view that is a child of the UISearchControllerView.
I've found a workaround to manually add back the searchbar as a subview of the UISearchControllerView container child. This is implemented in the delegate function (from UISearchControllerDelegate) didPresentSearchController:
func didPresentSearchController(searchController: UISearchController) {
if searchController.searchBar.superview == nil {
for searchCtrlChildView in searchController.view.subviews {
if searchCtrlChildView.frame.origin == CGPoint(x: 0, y: 0) { //Discriminate if by chance there was more than one subview
searchCtrlChildView.addSubview(searchController.searchBar)
break
}
}
}
}
I've also filed a radar to Apple on this as it is not fixed in iOS 8.4
Check the way I had my searchBar it in viewDidLoad
I have my viewController embedded in NavigationController too
My code (hope it helps) :
class myTableViewController: UITableViewController,UISearchResultsUpdating,UISearchControllerDelegate,UISearchBarDelegate
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()

UISearchController dismisses VC upon hitting cancel button

So, I am currently trying to replace the depricated searchDisplayController in one of my projects with UISearchController and I am running into this problem.
If there are no results in the search (the UITableView is empty) the whole ViewController is dismissed. This does not happen when the search results are not empty. I wan't to make it clear I am not using a UITableViewController. Instead I have a regular VC with a UITableView in it.
Here is some of my code:
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
controller.delegate = self
controller.searchBar.delegate = self
self.studentTable.tableHeaderView = controller.searchBar
return controller
})()
....
}
Now, if I add this function to the equation the cancel button always dismisses the VC.
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
resultSearchController.active = false
}
So why exactly does setting the searchController.active = false dismiss the VC? Is it because it is using the same UITableView as the VC? I believe that the old searchDisplayController would just display a UITableView over the one being used. If this is the case is there a way to override the dismissVC?
this is also Happening to me. The Way I Solve it is by Replacing:
resultSearchController.active = false
with
resultSearchController.searchBar.text = ""
resultSearchController.searchBar.resignFirstResponder()
I Hope this helps you :-)
2018 Just wanna share the fruits of my 1-2 hours debugging.
I had multiple issues with using UISearchController with UITabBarController, namely:
This one, this very question of the OP. Hitting cancel button dismisses the screen that is presenting the searchController.
The tab (or the screen) becomes black, Tab Bar and UISearchController giving black screen
Using UISearchController inside the title view of the navigation bar of UINavigationController in both iOS 10, 11, and 12, like this questions. UISearchBar increases navigation bar height in iOS 11
And for the solution for #3, since we're already here: https://stackoverflow.com/a/53264329/3231194
Finally, the ONLY solution that I have been seeing all this time is adding this code:
self.definesPresentationContext = true
The issue is that I was putting this in a wrong function.
Remember, that solution solved the #1, and #2 problem that I had. Nothing more, nothing less.
Where to add that? Inside the viewDidAppear. That's it!

UISearchbar (UISearchResultsUpdating) with Segue is still visible

I have a problem with a UISearchBar. When ill search some Text in combination with an UITableView, and ill click on one result Cell, the UISearchBar is still visible in the next View Controller. If ill go back (with Segues) - the UISearchbar is still there (with the Keyword)
So after ill click on one result, ill get (in the next View Controller):
Ill use it this way:
class ...: UITableViewController, UISearchResultsUpdating {
var filterSearchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
filterSearchController.searchResultsUpdater = self
filterSearchController.hidesNavigationBarDuringPresentation = false
filterSearchController.dimsBackgroundDuringPresentation = false
filterSearchController.searchBar.searchBarStyle = .Minimal
filterSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = filterSearchController.searchBar
Any ideas what could be a problem?
You need to dismiss the UISearchController yourself before transitioning to the next view controller with:
filterSearchController.active = false

Resources