Reputation: 8563
In iOS 5, is there a way to never hide the search bar in a UITableViewController
?
Upvotes: 0
Views: 1382
Reputation: 2412
I know it's an old question, but I found out a solution for this, which works with the classic UITableViewController and UTSearchDisplayController.
I created a container view for the searchBar 1st then put the searchbar inside it. The container must not clip to bounds. After this you can change the position of the searchbar relative to the container. One problem with this that this way the searchbar not handle user interactions. So we need to use our own container which get the events below its real frame.
Our container class:
@interface _SearchContainerView : UIView
@end
@implementation _SearchContainerView
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
if (self.subviews.count > 0) {
UISearchBar *searchBar = (UISearchBar *) self.subviews[0];
CGRect f = searchBar.frame;
f = CGRectMake(0, 0, f.size.width, f.origin.y + f.size.height);
if (CGRectContainsPoint(f, point)) return YES;
}
return [super pointInside:point withEvent:event];
}
@end
If you create the searchBar programmatically you can set the this up with a following like code:
- (void)setSearchEnabled:(BOOL)searchEnabled {
if (searchBar == nil && searchEnabled) {
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 44)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar
contentsController:self];
searchBar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin
| UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
searchContainer = [[_SearchContainerView alloc] initWithFrame:searchBar.frame];
[container addSubview:searchBar];
container.clipsToBounds = NO;
self.tableView.tableHeaderView = container;
} else {
[searchBar removeFromSuperview];
self.tableView.tableHeaderView = nil;
searchBar = nil;
searchDisplayController = nil;
searchContainer = nil;
}
}
Then you can change the position based on the tableView's scroll position:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (searchBar == nil || searchDisplayController.isActive) return;
CGRect b = self.tableView.bounds;
// Position the searchbar to the top of the tableview
searchBar.frame = CGRectMake(0, b.origin.y, b.size.width, 44);
}
And the last part is to restore everything after searching:
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
// Restore header alpha
searchContainer.alpha = 1.0;
// Place the searchbar back to the tableview
[searchBar removeFromSuperview];
[searchContainer addSubview:searchBar];
// Refresh position and redraw
CGPoint co = self.tableView.contentOffset;
[self.tableView setContentOffset:CGPointZero animated:NO];
[self.tableView setContentOffset:co animated:NO];
}
Upvotes: 0
Reputation: 25907
I wouldn't recommend a UITableViewController
for that then, a UIViewController
with a UITableVIew
and UISearchBar
on top of it and not on the header would do the job. In a more personal opinion, I wouldn't recommend UITableViewController
for anything, I find it too much strict for what it really offers. If for some reason I am using a UITableViewController
and the customer asks me to add a new element to the screen, I am basically screwed.
Upvotes: 7