I'm working on implementing a basic searchbar progmatically. I can't figure out how to make the searchbar stick to the header as the table scrolls. here is my code for loading the searchbar :
-(void)loadbar{
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
self.tableView.tableHeaderView = searchBar;
}
Search bar inherits from UISearchBar and searchDisplayController inherits from UISearchDisplayController
Thanks!
A table's header view scrolls with the table. If you don't want the search bar to scroll with the table view, you can't set the search bar as the header view.
You have three options.
Add the search bar to the navigation bar
Make the search bar a subview of the tableview. Implement the scrollViewDidScroll: delegate method for the table view and adjust the position of the scroll bar as the table scrolls.
Don't use UITableViewController. Use UIViewController and add your own table view. Add the search bar at the top and the table view below the search bar.
Solution
Use a one-section table view and set the search bar as the section header.
Discussion
Before, iOS was able to recognize when a search bar was in the table view header. In that case, the search bar was hidden under the navigation bar and it was possible to scroll down to reveal it. When in use, the search bar was fixed at the top of the window, not scrolling with the table view content. Since recently, this behavior is broken: the search bar scrolls with the cells.
In the proposed solution, we set the search bar as a section header. A section header remains visible until we scroll passed the end of that section. Thus, if we only have one section, the search bar is always visible.
Objective-C
// Class members
UISearchBar *searchBar;
- (void)viewDidLoad {
// Inherited
[super viewDidLoad];
// Search Bar
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchBar.delegate = self;
searchBar.barStyle = UISearchBarStyleMinimal;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// It is mandatory to have one section, otherwise the search bar will scroll
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// TODO: Return the number of elements in the table
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return searchBar.frame.size.height;
}
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return searchBar;
}
Related
I have page controller in which I added two tableviews. In each header of tableview search controller added, also viewForHeader method return "Recent" and "Other" view's.
My problem is the search bar does not appear when the search bar clicked.
It appear to move up, I cant see what I am typing there.
There may be the possibility that the search bar is hidden behind "Connection","Message" tab.
How to keep search bar at same position when keyboard become first responder?
any help will appreciated.
Have u used below lines of code at ViewDidLoad
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
[self.view bringSubviewToFront:searchBarRef]; // add this line where ever u need..!
-(void)loadSearchBar {
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 64)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
self.tableView.tableHeaderView = searchBar;
}
Call this loadSearchBar method at ViewDidLoad.
This will add search bar to TableView.
I'm adding search bar on table header and floating it in scrollViewDidScroll method, but when i scroll without click on search bar(i.e. i go to the view and do scroll) then search bar doesn't stay on top but it scroll up with table however once i click on search bar and click cancel button on search bar and then if i scroll the table, search bar stays on top.here is my code-
-(void)viewDidLoad {
[super viewDidLoad];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchBar.delegate = self;
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
searchDisplayController.searchResultsDelegate = self;
UIView *tableHeaderView = [[UIView alloc] initWithFrame:searchDisplayController.searchBar.frame];
[tableHeaderView addSubview:searchDisplayController.searchBar];
[tableView setTableHeaderView:tableHeaderView];
isSearching = NO;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
UISearchBar *searchBar = searchDisplayController.searchBar;
CGRect searchBarFrame = searchBar.frame;
if (isSearching) {
searchBarFrame.origin.y = 0;
} else {
searchBarFrame.origin.y = MAX(0, scrollView.contentOffset.y + scrollView.contentInset.top);
}
searchDisplayController.searchBar.frame = searchBarFrame;
}
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
isSearching = YES;
}
-(void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
isSearching = NO;
}
Note that I'm using UITableViewController sub class and don't want to change it to UIViewController.
Any help would be appreciated.
Edit: I also using section header in this UITableViewController, in other UITableViewController there is no section header and this code working fine.Is this a problem with section header and table header together?
The reason why your searchbar is scrolling with the table contents is that you have put it directly IN the table, thus making it a child header section of the table. and that section ALWAYS scrolls…
Here is how this this can be achieved. And it is actually quite simple. (The following example relies on Storyboard, but the mechanism is the same whatever you are using) :
1) Use a UIVIewController and NOT a UITableViewController
2) Add a UITableView as the child of the parent UIView
3) Add a UISearchBarController also as a child view of the UIView, NOT as a child of the UITableView (UITableView and UISearchController are siblings)
you should have the following layout :
EDIT : The important thing to remember is to put the UISearchBarController ABOVE the sibling UITableView. Otherwise you may see the UITableView overlap the UISearchBarController when the latter is focused.
EDIT 2 : BTW, if you are using AutoLayout, remember to set the TOP constraint of the tableView relative to the SearchBar…
Run it and admire the result.
Hope this helps.
There is not a way to maintain the header of a tableView fixed
1- could use an UIViewController instead of UITableViewController.
2- add subview (UIView) for header.
3- and add another subview for the tableview.
I am working on a project right now and I have to change the old code and using what have been done,
I am collecting information (item, label ..) by parsing Json,
in the old code we have a modal view that is divided in two parts :the first part display a picture of the Item and the second is a table-view with multiple button and a search bar,
what I have to do is to split that,
I need to have the search bar in a an other table view that I push by click on a button, when I click on a search-bar it push an other view controller which display a map,
the problem is what have been done used a storyboard and I have to do it programmatically!
How can I do it?
You can remove UISearchBar programmatically by sending removeFromSuperview message to it, and then go ahead and create a new instance of it and place it accordingly.
You can set the UISearchBar as the header of a tableView in a very simple way.
For eg. define your search bar like this
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
self.searchBar.barTintColor = weAskDefaultBkgColor;
self.searchBar.placeholder = #"Search users by their name or username";
self.searchBar.delegate = self;
Then, set this as tableView header
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
return self.searchBar;
}
I have a UITableViewController subclass, displayed in a modal view on an iPad. The view controller has a UISearchDisplayController subclass with a UISearchBar included in the header view of the table.
The subclassed UISearchDisplayController is called NoAnimationSearchDisplayController and I have overridden the - (void)setActive:(BOOL)visible animated:(BOOL)animated
method to prevent the search bar from animating into the navigation bar when it's set to active. The method override is below...
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if (self.active == visible) {
return;
}
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
The problem I'm having, is that when I have searched, and results are displayed in my search display controller's table view, everything looks fine untill i try to scroll down the list, at this point the content within the cells appears above the search bar, as shown in the following screen:
The search bar is set to UISearchBarStyleMinimal and transparency is enabled. Can anyone let me know how to stop this content overlapping the search bar? Ideally the content would disappear under the search bar as if it was the end of the view.
The answer was to manually change the frame of the table view provided by the UIsearchDisplayController in the appropriate delegate method...
- (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView {
/**
* Remove content inset automatically set by UISearchDisplayController as we are forcing the
* search bar to stay in the header view of the table, and not go into the navigation bar.
*/
[tableView setContentInset:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)];
/**
* Recalculate the bounds of our table view to account for the additional 44 pixels taken up by
* the search bar, but store this in an iVar to make sure we only adjust the frame once. If we
* don't store it in an iVar it adjusts the frame for every search.
*/
if (CGRectIsEmpty(_searchTableViewRect)) {
CGRect tableViewFrame = tableView.frame;
tableViewFrame.origin.y = tableViewFrame.origin.y + 44;
tableViewFrame.size.height = tableViewFrame.size.height - 44;
_searchTableViewRect = tableViewFrame;
}
[tableView setFrame:_searchTableViewRect];
}
Be sure the search bar is not translucent enabled ( on storyboard/xib ) or by code.
Then make the background to white or whatever color you want.
I want to add a search on top of a UITableViewController, but I want the field to be hidden initially (like Notes app) until the user pulls down to reveal it. How can I achieve this?
Thank you,
You should use UITableView's tableHeaderView. When done in code, it looks like this:
-(void)viewDidLoad
{
[super viewDidLoad];
UISearchBar *searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(self.tableView.bounds.origin.x, self.tableView.bounds.origin.y, self.tableView.bounds.size.width, 44.0)];
self.mySearchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.mySearchDisplayController.searchResultsDelegate = self;
self.mySearchDisplayController.searchResultsDataSource = self;
self.mySearchDisplayController.delegate = self;
self.tableView.tableHeaderView = searchBar;
}
You can use a tableview searchbar with the searchbar delegate.
On the viewDidLoad method you can manually scroll up the tableview. You can set an IBOulet on the searchbar to access its frame's height to know its height.