UISearchController searchbar hides the first cell in tableview - uitableview

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

Related

Swift ios11 NavigationItem SearchBar won't hide completely

Having an issue with adding a search controller to a navigationItem in iOS11 / Swift 4.
Basically everything works as expected for the most part, pull down will reveal the search bar and searching works fine. However when trying to hide the search bar by scroll back up... the bar won't hide completely and remains as a thin strip (see below).
I have declared my search controller as follows:
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.scopeButtonTitles = ["All", "Samples"]
searchController.searchBar.delegate = self
navigationItem.searchController = searchController
Before (scroll down to reveal search bar):
After (scroll up to hide):
As discussed in this Apple forums thread.
When the value of this hidesSearchBarWhenScrolling is true, the search bar is visible only when the scroll position equals the top of your content view, that's in case you are using a UIViewController, which view property is a normal UIView (It is not a subclass of UIScrollView).
Instead, try to use UITableViewController or ScrollView, it should work as expected
In my case it was happening only when there was a small num of items in the table.
I came to a non-technical, but rather a logical solution to show the search bar only when there are >10 items in the list. There is no need to have search when you have only a few items anyway.
Try to add this
self.navigationItem.hidesSearchBarWhenScrolling = true

iOS - segmentedControl disappears after using searchBar

Through Storyboard, I have created a ViewController with a UITableView and a SegmentedControl on top. Programatially, I have added a SearchController as the TableView's header.
This is what happens when I launch the app:
It works perfectly.
But when I click on the search bar, it already messes up a bit. It's easy to fix by hiding the SegmentedControl though.
Now the problem appears when I finish my search:
The SegmentedControl disappears. Whenever I click on the searchbar again, it comes back, just like in the picture number 2, but if I cancel again, it disappears.
I have tried removing it from the view and adding it again once the user stops searching, but it changes nothing. Here is my code:
searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
searchController.searchResultsUpdater = self;
searchController.dimsBackgroundDuringPresentation = NO;
searchController.searchBar.delegate = self;
self.tableView.tableHeaderView = searchController.searchBar;
searchController.searchBar.scopeButtonTitles = #[];
self.definesPresentationContext = YES;
[searchController.searchBar sizeToFit];
What can I change?
searchController.searchBar.showsScopeBar = YES;

UISearchController searchBar disappears on first click

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
}

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.

How do I use UISearchController in iOS 8 where the UISearchBar is in my navigation bar and has scope buttons?

I'm trying to use the new UISearchController from iOS 8, and embed its UISearchBar in my UINavigationBar. That's easily done as follows:
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.delegate = self
searchController.searchBar.delegate = self
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.titleView = searchController.searchBar
But when I add the scope buttons:
searchController.searchBar.showsScopeBar = true
searchController.searchBar.scopeButtonTitles = ["Posts, Users, Subreddits"]
It adds the buttons behind the UISearchBar and obviously looks very odd.
How should I be doing this?
You're bumping into a "design issue" where the scopeBar is expected to be hidden when the searchController is not active.
The scope bar buttons appear behind (underneath) the search bar since that's their location when the search bar becomes active and animates itself up into the navigation bar.
When the search is not active, a visible scope bar would take up space on the screen, distract from the content, and confuse the user (since the scope buttons have no results to filter).
Since your searchBar is already located in the titleView, the (navigation and search) bar animation that reveals the scope bar doesn't occur.
The easiest option is to locate the search bar below the
navigation bar, and let the searchBar animate up into the title
area when activated. The navigation bar will animate its height,
making room to include the scope bar that was hidden. This will all
be handled by the search controller.
The second option, almost as easy, is to use a Search bar button
icon, which will animate the searchBar and scopeBar down into
view over the navigation bar.
- (IBAction)searchButtonClicked:(UIBarButtonItem *)__unused sender {
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.definesPresentationContext = YES;
self.searchController.searchBar.scopeButtonTitles = #[#"Posts", #"Users", #"Subreddits"];
[self presentViewController:self.searchController animated:YES completion:nil];
}
If you want the searchBar to remain in the titleView, an animation
to do what you want is not built in. You'll have to roll your own
code to handle the navigationBar height change and display your own
scope bar (or hook into the internals, and animate the built-in
scopeBar down and into view).
If you're fortunate, someone else has written willPresentSearchController: code to handle the transition you want.
If you want to always see a searchBar and scopeBar, you'll probably have to ditch using the built-in scopeBar, and replace it with a UISegmentedControl which the user will always see, even when the search controller is not active.
Update:
This answer suggested subclassing UISearchController to change its searchBar's height.

Resources