4
votes

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.

3
After the hiding of the search bar, the table has 2 rows, each 70px height, table height=367, content offset.y=0, content inset.top=-75, and inset.bottom=0, all as expected. What's getting me stuck here is what causes the "bottom bounce"? The scroll view shouldn't allow me to scroll when the content is only 140px high and the view is 367 high, but why I can scroll that first row away?danh

3 Answers

11
votes

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

0
votes

Go with "alpha" approach :

[controller.searchBar setAlpha:0.0]; 

or

[controller.searchBar setAlpha:1.0]; 
0
votes

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.