danh danh - 3 months ago 27
iOS Question

Hide UITableView search bar

I have a UITableViewController with a UISearchDisplayController setup in the standard way (with the search bar inside the tableView). I'd like the search bar to start out hidden - really hidden, not merely scrolled away as in this solution. Then I'd like to present the search UI when the user presses a button, and hide it again (really hide it) after the user selects one of the items found in the search.

Here's the almost working code for that:

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];

self.searchDisplayController.searchBar.prompt = @"Add an item";
self.searchDisplayController.searchBar.placeholder = @"Type the item name";

// i do this to trigger the formatting logic below
[self.searchDisplayController setActive:YES animated:NO];
[self.searchDisplayController setActive:NO animated:NO];
// rest of my view will appear
}

- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {

NSTimeInterval duration = (self.isViewLoaded && self.view.window)? 0.3 : 0.0;
__block CGFloat searchBarHeight = controller.searchBar.frame.size.height;

[UIView animateWithDuration:duration animations:^{
self.tableView.contentOffset = CGPointMake(0, searchBarHeight);
self.tableView.contentInset = UIEdgeInsetsMake(-searchBarHeight, 0, 0, 0); // trouble here, I think
} completion:^(BOOL finished) {
controller.searchBar.hidden = YES;
}];
}


to show

- (IBAction)pressedAddButton:(id)sender {

self.searchDisplayController.searchBar.hidden = NO;
[self.searchDisplayController setActive:YES animated:YES];
}


I think I'm properly setting the content inset, but it behaves unexpectedly: with the code as shown, the table allows the content move up too far, i.e. with only two not-very-tall rows, I'm able to scroll down, pushing most of those two rows above the top of the table...like there's no bottom bounce. When I comment out the contentInset line, the table lets me pull the content down too far, leaving a big gap above row 0, presumably where the search bar is sitting hidden.

Much obliged if anyone can help.

Answer

To anyone else who might have this problem (which appears to be nobody) -

The only way forward I could find was to abandon the UITableViewController in favor of a UIViewController with a uiview whose children are the table view and search bar.

I manage the layout as above:

- (void)setSearchHidden:(BOOL)hidden animated:(BOOL)animated {

    UISearchBar *searchBar = self.searchDisplayController.searchBar;
    CGFloat searchBarHeight = searchBar.frame.size.height;

    CGFloat offset = (hidden)? -searchBarHeight : searchBarHeight;
    NSTimeInterval duration = (animated)? 0.3 : 0.0;

    [UIView animateWithDuration:duration animations:^{
        searchBar.frame = CGRectOffset(searchBar.frame, 0.0, offset);
        self.tableView.frame = UIEdgeInsetsInsetRect(self.tableView.frame, UIEdgeInsetsMake(offset, 0, 0, 0));
    } completion:^(BOOL finished) {if (!hidden) [searchBar becomeFirstResponder];}];
}

Except in a method that gets called when the add function starts and ends.

(About twice a year, I come to the conclusion that UITableViewController is more trouble than it's worth. Then, at approximately the same frequency, I forget I learned that).