UISearchController searchBar disappears on first click - ios

I have implemented a UISearchController in a TableView, pushed by a Navigation Controller.
First my problem was that whenever I click on the SearchBar, it disappears. It works when I enter some text, but it stays completely blank. Then I managed to semi solve the issue using this code:
- (void)searchForText:(NSString*)searchText
{
[self.view addSubview:villeSearchController.searchBar];
}
Which semi-works because now, when I click on the search bar, it blanks out, but if I enter one character, it appears again, and then it stays there, no matter what. Until I cancel the search, and click on it again, in that case it blanks out.
I have made some tests and this method (searchForText) is called on the very first click, so that isn't the reason.
Does anyone know how I can solve this issue and make the searchbar appear from the very first click?
EDIT:
This is how I initialize the SearchController:
villeSearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
villeSearchController.searchResultsUpdater = self;
villeSearchController.dimsBackgroundDuringPresentation = NO;
villeSearchController.searchBar.delegate = self;
villeTableView.tableHeaderView = villeSearchController.searchBar;
villeSearchController.searchBar.scopeButtonTitles = #[];
self.definesPresentationContext = YES;
[villeSearchController.searchBar sizeToFit];

This happened to me when the UISearchController was hiding the navigation bar. Setting this property fixed it:
UISearchController.hidesNavigationBarDuringPresentation = NO;

Try to check the navigationBar.translucent property - it should be YES when UISearchController will present the searchBar or else will be UI bugs.
Update from #SiavA
The better solution is use the extendedLayoutIncludesOpaqueBars property of the UIViewController. If you using the opaque navigation bar just set it in the true for controller which will be show UISearchController (not for navigationController).
E.g.
- (void)viewDidLoad {
[super viewDidLoad];
self.extendedLayoutIncludesOpaqueBars = !self.navigationController.navigationBar.translucent;
}

Place the SearchController inside a UIScrollView and it will work fine. This if you are using it in the section header or as a separate view

If you run into this problem in iOS11 (and especially if it worked pre iOS11), I had to change my UISearchController to be attached to the navigationItem rather than the tableView.
After setting parameters on my searchController, I used to do this:
tableView.tableHeaderView = searchController.searchBar
Now I have this:
navigationItem.searchController = searchController
The "translucent" fix would allow the controller to appear, but when I would try and unwind to a specific segue, I'd get a crash. Attaching the searchController to the navigationItem fixed both the display and the crash.

Setting isHidden of the navigation bar to false stopped the search bar from disappearing for me.
self.navigationController?.navigationBar.isHidden = false

Hi Guys there is a very simple solution for the issue.
-- this will solve major issues with collections of views and a parent view containing multiple viewcontrollers.
you don't need any below code if you have just remove it from your code
// searchController.definesPresentationContext = true
// self.definesPresentationContext = true
// self.extendedLayoutIncludesOpaqueBars = !(self.navigationController?.navigationBar.isTranslucent)!
I just add below code make sure you set searchController always set nil
if you are switching between viewControllers there may be some conflicts that can be cleared by setting it searchController nil in the setupsearchbar().
also, disable the searchController on viewDidDissapear(), it will solve the issue related to active search bar moving on to the next screen.
var searchController = UISearchController(searchResultsController: nil)
func setupSearchBar() {
searchController = UISearchController(searchResultsController: nil)
// adding search controller
searchController.searchResultsUpdater = self
// changing font color when user types
searchController.searchBar.searchTextField.textColor = .black
//allows select results from filtered table
searchController.searchBar.endEditing(true)
searchController.obscuresBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
self.tableView.tableHeaderView = searchController.searchBar
}
override func viewDidDisappear(_ animated: Bool) {
searchController.isActive = false
}

Related

iOS 11 navigation bar weird behaviour with search controller

General
I've been working on an application which was not touched since the release of iOS 11. Search controller in navigation bar was always the core part of it, this controller was used as a title view to always appear at the top of the screen.
Current Status
Some research lead me to the point where I could manage to replace the old navigationItem.titleView with the standard navigationItem.searchController property so iOS can handle everything related to the transition between views and so on.
.
Problem
This is the point where I got stuck because there is a huge glitch while going from "A" view controller to "B". I don't want to use large titles, the best solution would be to completely remove title and display only the search bar as the content of the navigation bar but unfortunately I couldn't get to that point.
Edit: These view's are embedded in a tab bar controller as well.
Search Controller setup code in viewDidLoad():
// Initialize search controller and set its important attributes
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = true
searchController.dimsBackgroundDuringPresentation = false
// Set placeholder text
searchController.searchBar.sizeToFit()
searchController.searchBar.placeholder = searchBarPlaceholder
searchController.searchBar.tintColor = UIColor.white
searchController.searchBar.returnKeyType = .search
// Replace title view with search bar
if #available(iOS 11.0, *) {
self.navigationItem.searchController = searchController
} else {
searchController.searchBar.barStyle = .black
self.navigationItem.titleView = searchController.searchBar
}

Custom position for UISearchBar

I'm currently trying to implement UISearchController and its associated UISearchBar.
I aim to have a UISearchBar just above my UITableView which goes top as soon as it has the focus, like the picture below (screenshot from my old UI with UISearchDisplayController, now deprecated):
I already tried to set my UISearchBar as header of the UITableView, it works well but I have 2 issues :
The search bar logically scrolls with the table view content
When the search bar takes the focus, it remains at the same position
Here is the way I configured my UISearchBar:
func configureSearchController() { // Method called in the viewDidLoad()
searchController = UISearchController(searchResultsController: nil)
searchController!.searchResultsUpdater = self
searchController!.dimsBackgroundDuringPresentation = false
searchController!.searchBar.placeholder = "searchfood.searchbar.placeholder".localized
searchController!.searchBar.sizeToFit()
searchController!.hidesNavigationBarDuringPresentation = false
print(searchController!.searchBar.frame)
// Place the search bar view to the tableview headerview.
foodsTableView.tableHeaderView = searchController!.searchBar
// Search bar
searchController!.searchBar.searchBarStyle = .prominent
searchController!.searchBar.barTintColor = ColorLSDP.corail
searchController!.searchBar.tintColor = ColorLSDP.beige
}
So I tried to remove the following lines:
foodsTableView.tableHeaderView = searchController!.searchBar
But when I did this, I was not able to see the UISearchBar anymore.
After checking some other SO topics, I just spotted that my UISearchBar was maybe hidden below my UINavigationBar. So I tried to add the following lines in the viewDidLoad() method:
self.navigationController?.navigationBar.isTranslucent = false
self.edgesForExtendedLayout = []
It changed nothing.
Anyway, it did not solve my main issue which is having this search bar initially positioned like the screenshot above.
Is there a way to do this properly with the brand new UISearchController ?
Thanks a lot for your upcoming answers,
Regards,
Seb R.

self.definesPresentationContext = true: leads to black screen?

let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
// searchController.definesPresentationContext = true
self.definesPresentationContext = true
When the search bar is active, with text in it, and I go to another tab and then back, the controller is black, apart from the actual search bar. Things go back to normal when I cancel and empty the search text field.
My question is basically identical to this question: UISearchController causes black screen Swift 2.0
Except that that answer does not solve my problem as you can see. What does solve it is if I change self to searchController, thus: searchController.definesPresentationContext = true. But this results in the search bar appearing in the next controller I tab to. Very confused, please help.
I am using a tableview embedded in a navigation controller and tab bar controller. viewDidDisappear is not being called when the search is active.
Not a solution per se, but a workaround, this stackeroverflow post helped:
TableView with SearchController - DEINIT not called. I am not sure if this is some kind of apple bug.
Apparently I am not supposed to use self.definesPresentationContext = true at all. This makes my search appear in all my tabs. But at least viewDidDisappear is called.
In viewDidDisappear, I can hide the search bar with searchController.searchBar.hidden = true and show the bar again in viewDidAppear.
in the AppDelegate.swift
window?.backgroundColor = UIColor.white

UITableViewContoller in UINavigationController with UISearchController wrong after back button

We have a UINavigationController with a UITableViewController. We have a UISearchController to filter the list of items in the table. When we tap a cell it navigates to the detail. But when we navigate back, its as if the UISearchBar is on top of the content... like instead of being in the table header, it is now over top of the table. How can we get it to behave as being in the table header.
func buildSearchBar() {
self.searchController.searchResultsUpdater = self
self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.dimsBackgroundDuringPresentation = false
self.definesPresentationContext = true
self.searchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = searchController.searchBar
}
Edit to add: we set all UINavigationBar appearance to be translucent = NO; This is the line of code that seems to break it for us. Does that sound right to anyone else?
[UINavigationBar appearance].translucent = NO;
I had a similar problem. Add the following line to the viewDidLoad method of your view controller (self in the code you posted in your question).
self.definesPresentationContext = true;
This fixed the problem for me.

UISearchController searchbar hides the first cell in tableview

I have a tableview with a search bar. The search bar is provided by a UISearchController. When I add the search bar to the header view of the table, the first row of the table gets covered by the search bar.
How do I prevent the search bar from hiding the first row?
I have this snippet in viewDidLoad:
self.searchController = UISearchController(searchResultsController: nil)
self.searchController.searchResultsUpdater = self
self.searchController.searchBar.delegate = self
self.tableView.tableHeaderView = self.searchController.searchBar
self.searchController.dimsBackgroundDuringPresentation = false
self.searchController.searchBar.sizeToFit()
It seems that you have to explicitly set the scope button titles array if you don't have scope button titles.
self.searchController.searchBar.scopeButtonTitles = [NSArray array];
Found this issue to be a layout constraints issue. Resolved by dropping all of my constraints in the view containing my searchcontroller and adding back in individually until I found the offending constraint. Using Xcode 7.1

Resources