iPhone: Hide UITableView search bar by default

I used the Interface Builder to create a table view, to which I added the library's Search Bar and Search Display Controller to add search functionality. However, IB set it up so that the bar is visible at the top of the screen when the view is first displayed.

I'd like to know how to have the search bar be hidden by default but still scrollable with the table view (see Apple's Mail application for an example). I've tried calling scrollRectToVisible:animated: in viewDidLoad to scroll the table view down, but to no avail. What's the preferred way of hiding the search bar by default?


First make sure, to add the UISearchBar to the tableHeaderView of the UITableView so that it gets scrolled with the table's content and isn't fixed to the top of the view.

The searchbar isn't counted as a row in the tableview, so if you scroll the top of the tableview to the first row, it 'hides' the searchbar:

[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];

or in Swift:

yourTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)

Make sure to not scroll the tableview before it contains data (scrollToRowAtIndexPath will raise an exception if the given indexPath does not point to a valid row (i.e. if the tableview is empty)).


Dont' add the UISearchBar as a subview of the UITableView, this isn't necessary.

The UITableView has a tableHeaderView property that is perfect for this:

- (void) viewDidLoad {
    [super viewDidLoad]; 
    self.searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
    self.searchBar.showsCancelButton = YES;    
    self.searchBar.delegate = self;
    self.tableView.tableHeaderView = self.searchBar;     
}

If you don't want to see it by default:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.tableView setContentOffset:CGPointMake(0, 44)];
}

I also get the cancel button to hide it again.... (and remove the keyboard)

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self.tableView setContentOffset:CGPointMake(0, 44) animated:YES];
    [self.searchBar resignFirstResponder];
}

The contentOffset was noted in the comments by Tim and Joe D'Andrea, but this is a bit expanded by adding an animation to hiding the search bar. I noticed it is a bit unexpected for the search bar to just disappear.

A little update for those who want to target iOS 4.0 and above, try this:

[UIView animateWithDuration:0.4 animations:^{
    self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);
 } completion:nil];

Previous answer:

[UIView beginAnimations:@"hidesearchbar" context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationBeginsFromCurrentState:YES];

self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);

[UIView commitAnimations];