Hide UITableView search bar

2019-05-14 02:08发布

问题:

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.

回答1:

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).



回答2:

Go with "alpha" approach :

[controller.searchBar setAlpha:0.0]; 

or

[controller.searchBar setAlpha:1.0]; 


回答3:

If you have enough entries in your table, you can do the following:

[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];

This only works if there are enough entries to fully fill the screen. Of course, if you only have one or two entries, you may not care to hide the search bar.