I have a UITableView and am currently working on adding a custom search bar at the top consisting of a UIView with a UITextField inside of it. As is standard for iOS apps, the search bar should only be visible when the table view is scrolled to the top — when scrolling down it should disappear off the screen along with the other cells.
However, I cannot figure out a way to achieve this effect. If I place the search bar at the top of the table view, it will overlay the cell beneath it. If I place it 50 pixels above the table view, it is not possible for the user to select it since it will automatically disappear when the user releases their finger from the screen.
Can someone please enlighten me as to how to achieve this effect?
Usually you just use UISearchBar
as a tableViewHeader
for your table view. If you want it hidden when the user enters the screen (like it's done in most native apps) you can just set contentOffset
for the tableView
in viewWillAppear
.
And I am pretty sure that's in fact how they do it. And if you think about it it's what tableHeaderView
is meant for.
Try something like this:
- (void)viewDidLoad
{
[super viewDidLoad];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0., 0., 320., 44.)];
self.tableView.tableHeaderView = searchBar;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
CGPoint contentOffset = self.tableView.contentOffset;
contentOffset.y += CGRectGetHeight(self.tableView.tableHeaderView.frame);
self.tableView.contentOffset = contentOffset;
}
Note that in iOS 7 you should not just set the contentOffset
of your tableView
to CGPointMake(0., CGRectGetHeight(self.tableView.tableHeaderView.frame))
if your viewController
has automaticallyAdjustsScrollViewInsets
set to YES
, since it probably will not be CGPointZero
in viewWillAppear:
@dariaa's answer updated for Swift 3:
override func viewDidLoad() {
super.viewDidLoad()
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 44))
self.tableView.tableHeaderView = searchBar
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
var contentOffset: CGPoint = self.tableView.contentOffset
contentOffset.y += (self.tableView.tableHeaderView?.frame)!.height
self.tableView.contentOffset = contentOffset
}
Though you'll probably need to set the searchBar as a property if you want to use it.
If you only want your search to be visible when the UITableView is scrolled all the way to the top, make a UITableViewCell subclass that houses your UISearchBar. Then, in tableView:cellForRowAtIndexPath, check if the indexPath is (0,0). This is the table view telling you it is creating the cell at the very top, so then just create your search bar cell instead of your default cell.
Code would look something like this:
- (void)viewDidLoad
{
[self.tableView registerClass:[SearchBarCell class] forCellReuseIdentifier:@"SearchBarCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0 && indexPath.section == 0) {
//this is the cell that displays the UISearchBar
SearchBarCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SearchBarCell"];
return cell;
}
else {
//create your usual table view cell normally
}
}
There may be a cleaner way to determine the row and section of the indexPath, but I'm writing this code off the top of my head and don't recall a better way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With