UITableView contentSize wrong when using UISearchBar

Placing the UISearchBar inside a container UIView mostly fixes the problem.

- (void)viewDidLoad
{
    [super viewDidLoad];
    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    _tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:_tableView];

    UIView *searchBarContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
    _searchBar = [[UISearchBar alloc] initWithFrame:searchBarContainer.bounds];
    [searchBarContainer addSubview:_searchBar];

    _searchController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
    _searchController.delegate = self;
    _searchController.searchResultsDataSource = self;
    _tableView.tableHeaderView = searchBarContainer;
}

Unfortunately the UISearchBar glitches in some scenarios that I couldn't isolate yet. I opted to calculate the contentSize manually by adding the height of all cells.


Starting from iOS11, UITableView uses estimate row/header/footer height to calculate initial contentSize by default. In fact, if you tap on the search bar and dismiss the keyboard, content size will have the correct value.

To fix this behavior, set estimate row, header and footer height to 0 in IB instead of Automatic:

enter image description here

or just do it programmatically:

self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;