Giulio Colleluori
Giulio Colleluori

Reputation: 1361

UISearchBar scope buttons in UITableView Header hide the first row of the table view

I have a problem: I have a UIView that contains a UISearchBar as a header of a UITableView. The problem is that whenever I tap on the UISearchBar, the animated scope buttons come out hiding part of the first row of the table. I looked at a lot of similar questions but none of the answers worked. Is there a way to add a bottom constraint to the headerView so that the UITableView goes down of the height of the scope buttons view whenever the UISearchBar is focused and being edited?

This is the code where I add the UISearchController:

searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
searchController.searchBar.scopeButtonTitles = ["Groups", "People"]
tableView.tableHeaderView = searchController.searchBar
searchController.searchBar.delegate = self
searchController.searchBar.sizeToFit()
searchController.searchBar.barTintColor = darkGreen
searchController.searchBar.tintColor = yellow
searchController.searchBar.backgroundColor = darkGreen
tableView.sectionHeaderHeight = UITableViewAutomaticDimension

If you could please let me know how could I fix this bug I would really appreciate it!

Thanks!

Upvotes: 4

Views: 3526

Answers (6)

Sven van den berghe
Sven van den berghe

Reputation: 71

In my case, setting the scope button titles was enough to get the scope bar to show, but the search control/tableview is not properly initialised, and showing all rows, until I inserted

searchController.searchBar.showsScopeBar = true

Upvotes: 2

Marmoy
Marmoy

Reputation: 8079

When I experienced this it came down to what I can only conclude is a bug. The only way to fix it was to setup the layout in a very specific way:

  1. Make sure that the tableview is placed behind all other views, i.e at the top of the list of views in the viewcontroller's root view as shown in the document outline for the storyboard file.

enter image description here

  1. Ensure that there is a vertical distance constraint between the tableview's top and the top margin of the viewcontroller's root view. Set it up exactly as in the screenshot. If the order of the two views is reversed, then it will not work. If the constraint is to the superview top and not to the superview top margin, then it will not work. If the constraint is to the top layout guide, then it will not work.

enter image description here

I have never experienced anything like this in all the time I have worked with, and it is pure luck that I had a working project to compare with and finally figure out how to get it right.

Upvotes: 0

Fenil
Fenil

Reputation: 1204

This is happening because the HeaderView height is set to the Searchbar height which is 44 initially. But once you click on Searchbar the Searchbar is presented modally and moves to the top along with Scope buttons but the underlying HeaderView height is still the same which is 44 instead of 88 (Searchbar height + Scope button height)

For this how I have handled is -

1) Implement - UISearchControllerDelegate and assign using searchController.delegate = self;

2) Override UISearchControllerDelegate methods -

-(void) didPresentSearchController:(UISearchController *)searchController {
    [self fnResizeTableViewHeaderHeight];
}

-(void) didDismissSearchController:(UISearchController *)searchController {
    [self fnResizeTableViewHeaderHeight];
}

3) Resize TableView header height depending on the search bar height -

-(void) fnResizeTableViewHeaderHeight {
    CGFloat height = [searchController.searchBar systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    UIView *headerView = self.table_view.tableHeaderView;

    CGRect frame = headerView.frame;

    frame.size.height = height;
    headerView.frame = frame;

    self.table_view.tableHeaderView = headerView;
}

Upvotes: 10

cwilliamsz
cwilliamsz

Reputation: 718

Set

searchController.hidesNavigationBarDuringPresentation = false
definesPresentationContext = false

This worked for me

Upvotes: 2

Dabbler
Dabbler

Reputation: 1

I was having the exact same problem. It's caused by the constraint of the UITableView to the top layout guide (the navigation bar). Navigation bar slides up to reveal the searchbar and/or scope buttons and it pulls the top of the table with it. Break that constraint and you'll find that the searchbar and scope buttons move up, but the top of the first row of the table stays put. Now you've just got to figure out how to constrain the table so it has a decent height across all devices....

Upvotes: 0

muneeb
muneeb

Reputation: 2511

searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = false
searchController.searchBar.scopeButtonTitles = ["Groups", "People"]
tableView.tableHeaderView = searchController.searchBar
searchController.searchBar.delegate = self
searchController.searchBar.sizeToFit()
searchController.searchBar.barTintColor = darkGreen
searchController.searchBar.tintColor = yellow
searchController.searchBar.backgroundColor = darkGreen
tableView.sectionHeaderHeight = UITableViewAutomaticDimension

Just set definesPresentationContext to false

Upvotes: 0

Related Questions