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.
Related
I have a UITableView with a UISearchController search bar in the UINavigationBar, all works perfectly, but when I push a result of the searched results of the UISearchController, and I come back the UITableView is under the NavBar, this is how I initialize the UISearchController:
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.delegate = self;
self.searchController.searchResultsUpdater = self;
self.searchController.searchBar.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.searchBar.placeholder = NSLocalizedString(#"Local Search", #"");
self.searchController.searchBar.frame = CGRectMake(0, -5, [UIScreen mainScreen].bounds.size.width, 44);
ctrl = [[UIView alloc] initWithFrame:CGRectMake(0, 0,[UIScreen mainScreen].bounds.size.width, 44)];
ctrl.backgroundColor = [UIColor clearColor];
ctrl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[ctrl addSubview:self.searchController.searchBar];
self.navigationItem.titleView = ctrl;
self.definesPresentationContext = YES;
The search bar is displayed perfectly in the UINavigationBar, then when I search something and I push the view controller of one results like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailListController *detailList = [[DetailListController alloc] init];
[self.navigationController pushViewController:detailList animated:YES];
}
when I come back to the UITableView doing this:
[self.navigationController popViewControllerAnimated:YES];
the UITableView is under the UINavigationBar, how I can fix this?
thanks
I had exactly the same problem, setting extendedLayoutIncludesOpaqueBars to YES/true in view controller, that presents search controller, seems to fix it.
self.extendedLayoutIncludesOpaqueBars = YES
As a word of caution: setting this property changes value of scroll view's vertical content offset.
This is an extremely frustrating bug in UIKit. What appears to be happening is that the presenting view controller's top layout guide get reset to 0, meaning it is now underneath the nav bar. The layout guide is a read only property, so you can't fix it by editing directly. However, I did come up with a hack to get it to reset to the correct value. Add this to your UISearchControllerDelegate:
- (void)didDismissSearchController:(UISearchController *)searchController
{
UINavigationController *nav = self.navController; // you muse save this earlier
// force to layout guide to reset by pushing a dummy controller and popping it right back
[nav pushViewController:[UIViewController new] animated:NO];
[nav popViewControllerAnimated:NO];
}
I have used UISearchController for years but today is the first time I am facing this issue
I used to set edgesForExtendedLayout = [] and extendedLayoutIncludesOpaqueBars = true and everything is fine
but today It is not, I needed to reverse it to edgesForExtendedLayout = .all
it may be useful to you too!
Ran into this issue today and resolved using a reference to the result view controller's safeAreaLayoutGuide
After refreshing your result table's contents, you can then call this method:
// NOTE: this method is used to fix a known UIKit bug where search results that do not have a content
// size that fills the view will be placed underneath the navigation bar when displayed. this hack
// fixes this issue by resetting the contentInset based on the content size.
private func adjustContentInsetForContentSize() {
if collectionView.contentSize.height > view.frame.height {
collectionView.contentInset = UIEdgeInsets.zero
} else {
collectionView.contentInset = UIEdgeInsets(top: view.safeAreaLayoutGuide.layoutFrame.origin.y, left: 0, bottom: 0, right: 0)
}
}
Essentially the issue is caused by having a result view that has a contentSize height that is smaller than the viewable region for the view. The results render find when the contentSize.height > view.frame.height, so this hack will force the content insets to properly respect the safe area layout guide.
I have added a UISearchController to my code using the following method:
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.scopeButtonTitles = #[];
self.searchController.searchBar.delegate = self;
self.tableView.tableHeaderView = self.searchController.searchBar;
[self.searchController.searchBar sizeToFit];
self.definesPresentationContext = YES;
This creates my search controller and adds it to the top of my tableView. Annoyingly it starts visible though:
I can hide it by sliding it up under the navigation bar which suggests the underlying functionality of the code is working but I can't get it to start hidden so I can slide it down.
I have tried adjusting the edge insets, I have tried setting the navigation bar to translucent, I have tried to go through the search bar tutorials online but nothing seems to be dealing with this issue.
Any help very welcome
Did you try setting the content offset of your table view?
[self.tableView setContentOffset:CGPointMake(0, self.searchController.searchBar.frame.size.height) animated:NO];
Here is for swift 4
tableView.setContentOffset(CGPoint(x: 0, y: searchController.searchBar.frame.size.height), animated: true)
From iOS 11.0 onwards you can use,
self.navigationItem.searchController = self.searchController;
The search bar will be hidden, unless you swipe down to reveal it.
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 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.
I have placed a UISearchBar in my UITableView.tableHeaderView. However it covers the searchBar by placing the viewable top to the first section header. I can only see the searchBar when I drag the tableView down. It is half covered and then can not be selected because releasing the tableView scrolling will rubber band it back out of view. Please help.
The following is placed in my UITableViewController viewDidLoad method:
UISearchBar *theSearchBar = [[UISearchBar alloc] init];
theSearchBar.delegate = self;
self.searchBar = theSearchBar;
[theSearchBar release];
self.tableView.tableHeaderView = self.searchBar;
The result is the following screenshots: http://imagebin.ca/view/6qNiwHR.html
It turns out that it was a sizing issue. I found a tutorial that places the following code in the set up:
[theSearchBar sizeToFit];
which make everything look perfect.
Since UISearchDisplayController uses an already established UISearchBar it doesn't eliminate the problem.
I think the tableHeaderView is not the best place to put your search bar.
I usually use a UISearchDisplayController:
searchController = [[UISearchDisplayController alloc]
initWithSearchBar:theSearchBar contentsController:self];
searchController.delegate = self;
searchController.searchResultsDataSource = self;
searchController.searchResultsDelegate = self;
It's pretty straight-forward and give some functions for searching (you have to implement them in the delegate/datasource, in this case your controller).
I usually do it from a nib but i think you just have to assign it to your viewcontroller :
self.searchDisplayController=searchController;
And if it doesn't show the view, you should add the view to the tableView directly.
You can look at the reference, or ask if you have some problems.