If you add a UISearchBar to your table view (see previous article) it’s just sitting there by default. Chances are you’d like to hide it when your table view first loads.
You can do this by adding the following method, and call it whenever you’d like to make it disappear (call it from your viewDidLoad method for example, or via an observer from another class):
[emember_protected]
1 2 3 4 5 6 7 8 9 10 11 |
- (void)hideSearchBar { // scroll search bar out of sight CGRect newBounds = self.tableView.bounds; if (self.tableView.bounds.origin.y < 44) { newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height; self.tableView.bounds = newBounds; } // new for iOS 7 [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:0 animated:YES]; } |
Now it’s hidden, users make a search, hit cancel… and then it comes back into view. Wouldn’t it be nice if we could hide it again after users are finished with their search? And sure we can! We’re already conforming to the UISearchBarDelegate protocol, so all we need to do is to implement the following method and react to the cancel button:
[emember_protected]
1 2 3 4 5 |
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { [self viewWillAppear:YES]; } |
We could implement the same code as above, or just call the viewWillAppear method again.
Note that you have to set the search bar’s delegate to your class for this to work. Searches are working fine when it’s not set, but to react to the cancel button it needs to be set (either in code or via the Connections Inspector in Interface Builder).
You can find a full demo project on GitHub: Table Search 2013 (updated for iOS 7)
[/emember_protected]
I forgot to mention how to bring up the search bar with an IBAction, now that it’s hidden. All we need to do is associate an action with a button (say that nice looking loupe search logo in a navigation bar), then make the search bar the first responder:
The goal can easily be accomplished with the help of setContentOffset of tableview. below is the code
self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height)
Thanks for sharing, Abdul – I’ll check it out!
Better to place this code under – (void)viewDidLoad method
as ViewDidAppear will cause the tableview to shift up every time you navigate to and from a child view.
Thanks David, very good tip – I’ve noticed that too. It’s not pretty indeed.
iOS 7 Update
Bringing up the search bar by making it the first responder no longer works in iOS 7: the cancel button won’t be responsive anymore. Instead, we can use this method:
Thanks to Janos Homoki for this tip.
Thanks million Jay!
I have one issue if you can help me with it, when I click on the search button it will show the search bar but the cancel button won’t work and you will be stuck in the search bar, the reason that I can see I when I click the search button it won’t go to the top where the search bar is, instead it will show it where you stop in the table view, but when I scroll to the top and I click the search button everything works fine.
Could you help me in this I really appreciate it.
I forgot to mention I am using the Xcode 5 for some reason all the problems came with it
Sorry for posting lots of comments, I just fixed the problem I discovered that i have two search bar declaration and didn’t know about it. now it is working fine all thanks to you!
No problem Sal, the more comments the merrier! Glad you could sort it out, it’s not the easiest exercise I find.
Considering that in jQuery Mobile it takes ONE additional parameter to create a searchable table view, such a basic feature is way to complicated in iOS.
iOS 7 – Update #2
I’ve noticed that when your table does not have a header, then the first cell will be slightly cropped at the top when the search controller is cancelled. There’s some new effect that makes this happen. It’s not noticeable when your table has a header, but if it does not it’s just plain annoying – and once again totally undocumented by Apple.
To avoid this, let’s buffer the space above the first cell by setting a height for our non-existent header on iOS 7:
Note that this phenomenon does not seem to happen in my Demo Project – but I have noticed it on other custom projects where the height of table view cells is larger than the default. Just thought I’d mention it.
iOS 7 – Update #3
If you’re hiding the search bar from another view via an observer, iOS 7 shifts the cells of all views up that listen to the observer. I guess this is expected behaviour, and iOS 6 just didn’t do it. To avoid this, hide the search bar in iOS 7 as usual, and also scroll the table to the top position:
For completion, here’s the full method:
The fun never stops with iOS 7 does it…
Thanks , U save my day, I was looking for days to solve this on ios7.
You’re very welcome 😉
UPDATE 2014
I’ve just finished recording a screencast that demonstrates how to do this here:
[self viewWillAppear:YES]; its not good
It was when I wrote this in 2013 😉 There’s an updated version of searchable table views for iOS 9 here: http://pinkstone.co.uk/how-to-create-a-searchable-uitableview-in-ios-9/