[![enter image description here][1]][1]I am facing issue with UISearchBar & UISearchDisplayController. When I click on searcher then it messes up with the Navigation bar. I have tried to fix with many codes but did not work. I am creating UIsearch bar and UISearchDisplayController via pragmatically. Please help. Any suggestion will be Great.
// Search Bar
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0,subView.frame.size.width, 52)] ;
searchBar.delegate=self;
//UISearchDisplayController
searchController=[[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self] ;
[searchController setDelegate:self];
[searchController setSearchResultsDataSource:self];
[searchController setSearchResultsDelegate:self];
[searchController.searchResultsTableView setDelegate:self];
Related
I have multiple view controllers which all use one class (we'll call it searchClass <NSObject>) I wrote that has a UISearchController for searching an external API. The user can tap the search icon and the search controller becomes active: [_searchClass.searchController setActive:YES]; It uses its own table view controller (not the one in each of the view controllers, because they aren't all table view controllers).
In my case I make the search bar appear in the navigation bar. Search works great, the user can select a search result and tap it for a detail view. The problem is when the user goes back (unwinds) from the detail view to the search results, there is a black gap about 44 pts tall that appears briefly above the table view and below the navigation bar, and then disappears.
Here is my setup. In the view controller:
self.definesPresentationContext = YES;
_searchClass = [SearchClass new];
_searchClass.navController = [self navigationController];
In the search class:
_searchTableViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"searchTableViewController"];
_searchTableViewController.tableView.delegate = self;
_searchTableViewController.tableView.dataSource = self;
_searchTableViewController.tableView.backgroundColor = [UIColor clearColor];
_searchTableViewController.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
_searchTableViewController.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectZero];
_searchTableViewController.definesPresentationContext = YES;
_searchController = [[UISearchController alloc] initWithSearchResultsController:_searchTableViewController];
_searchController.delegate = self;
_searchController.hidesNavigationBarDuringPresentation = NO;
_searchController.searchBar.delegate = self;
_searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
_searchController.searchBar.showsCancelButton = YES;
_searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
There are also the usual delegate methods for UISearchBar and UISearchController, and the code that displays the search bar, which uses an animation to replace the titleView of the navigation bar.
How do I get rid of that gap after unwinding back to the search results?
I found the solution, it's related to the UINavigationBar. For some reason setting the translucent property to NO seems to have caused this issue.
self.navigationBar.translucent = YES;
Setting it to YES (or omitting the line since it is the default) made it work properly. Since I still wanted to have the navigation bar be opaque, I did the following to make the nav bar translucent only during transitions, which seems to be where the issue lies:
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.navigationController.navigationBar.translucent = YES;
}
-(void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.navigationController.navigationBar.translucent = NO;
}
Definitely seems like a genuine iOS bug to me.
There is plenty of sample code out there, and I thought I was following it line for line; my code:
(void)viewDidLoad
{
[super viewDidLoad];
// init search bar
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchBar.delegate = self;
searchBar.showsCancelButton=YES;
// set up searchDisplayController
UISearchDisplayController *searchController = [[UISearchDisplayController alloc]
initWithSearchBar:searchBar contentsController:self];
searchController.delegate = self;
searchController.searchResultsDataSource = self;
searchController.searchResultsDelegate = self;
// display search bar in nav bar
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
}
With that code, shouldn't I see the search bar displayed in the navigation bar? All I see in the nav bar is the cancel button. I have declared the protocols <UISearchDisplayDelegate, UISearchBarDelegate> in my header file. What am I missing, or what could be going wrong? Thanks
Note:
Using self.navigationItem.titleView = searchBar, the search bar displays as expected. I wonder what are the advantages of the newer displaysSearchBarInNavigationBar method..
-- Edit by tassilo --
It looks like the search bar is added to the navigation bar, but then disappears.
The displaysSearchBarInNavigationBar property makes it so the search bar slides into the navigation bar when the user taps it, like what happens in the Apple Mail app. You still need to add the search bar to the view somewhere.
Best way to do this is to set the tableHeaderView of a UITableViewController to the search bar.
self.tableView.tableHeaderView = self.searchBar;
This line is your problem.
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
self.searchDisplayController is not the same as searchDisplayController, that you created.
So just replace self.searchDisplayController with searchDisplayController. Also, be sure that you don't have #synchronize searchDisplayController;
I'm struggling with the UISearchDisplayController and hope someone out there can help me out.
So basically I've got a UINavigationBar which has a "Search"-Button in it. When someone taps "Search" the UISearchDisplayController should get active and the UISearchBar should appear inside the UINavigationBar. Next to the SearchBar I've implemented a "Cancel"-Button which deactivates the SearchDisplayController and resets the UINavigationBar back to it's standard with the "Search"-Button.
My first problem is the gap between my SearchBar and the results-table or the gray overlay while the SearchDisplayController is active.
The second problem is that I can't reset my rightBarButtonItem to the default icon (magnifying-glass) after tapping cancel. It's nothing happening even when I try to set [self.navigationItem setRightBarButtonItem:nil]; it just remains with the "Cancel" button.
Here is my implementation: (The UI elements are added through my storyboard)
- (IBAction)btnSearchClicked:(id)sender {
[self.navigationController.navigationBar addSubview:self.searchController.searchBar];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelEditing)];
[self.searchController.searchBar setFrame:CGRectMake(0, 0, 250, 44)];
[self.searchController setDisplaysSearchBarInNavigationBar:YES];
[self.searchController setActive:YES animated:YES];
[self.searchController.searchBar becomeFirstResponder];
}
-(void)cancelEditing
{
[self.navigationItem setRightBarButtonItem:nil];
[self.searchController setActive:NO animated:YES];
[self.searchController.searchBar removeFromSuperview];
}
OK I came up with a solution for both problems.
The gap was occurring because of [self.searchController setDisplaysSearchBarInNavigationBar:YES]; which expected the NavigationBar to be translucent, so I've worked around by just enabling translucency on btnSearchClicked and deactivating it on cancel.
The problem with the button was resolved by deactivating setDisplaysSearchBarInNavigationBar in cancelEditing before accessing the setRightBarButtonItem property. Maybe that the setDisplaysSearchBarInNavigationBar-Option creates an new NavigationBar which doesn't respond to self.navigationItem.
I would like to add a searchbar to a UICollectionViewController, that's embedded the following way:
UItabbarController > UINavigationbarController > UICollectionViewController > SearchBar (!)
In this view, the search bar would replace the NavigationBar.
Under the same design, if I test the above with a UITableViewController, the searchbar shows up fine (both programmatically and via the Storyboard)
Problem is I can't get to add the search bar over the UICollectionViewController when I use the StoryBoard framework; it just sits in the middle of the view, and I'm clueless as to how to move it to the top. Plus, it always appears below the UICollectionview, so it's not visible.
So, taking the other route, programmatically:
-(void)viewWillAppear:(BOOL)animated{
self.searchBarTop = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[self.searchBarTop setPlaceholder:#"Enter your command here"];
self.searchDC = [[UISearchDisplayController alloc]initWithSearchBar:self.searchBarTop contentsController:self];
self.searchBarTop.delegate = self;
[[self navigationController] setNavigationBarHidden:NO animated:animated];
[self.navigationController.navigationBar addSubview:self.searchBarTop];
}
With this, the search bar shows up fine. But unfortunately, when I type in some text, it disappears above the view - presumably because the underlying navBar does so - (don't know why...)
I'm not sure exactly why the searchbar is fine with a UITableViewController, and why it is such a pain for a UICollectionViewController.
That said, anyone has a clue as to why the searchbar/navBar disappear, and how I can fix that ?
Any solution is welcome..
thanks !
-A
Add a Header and put the SearchBar in that (that is what I have done in the past). That being said, I have gotten in the habit of hardly ever using either a UITableViewController (unless I am implementing a StaticCell TableView) or a UICollectionViewController. What I would suggest is to implement a standard UIViewController and just add in your UICollectionView. Size the CollectionView down some and put the SearchBar at the top. This allows you to have a SearchBar that is always displayed (which my users generally like better than having to scroll to the top to change, edit a search)
I use the following code to add a UISearchBar to the UICollectionViewController.
Unfortunately I couldn't make UISearchDisplayController working.
- (void)viewDidLoad
{
[super viewDidLoad];
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.collectionView.frame), 44)];
self.searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
self.searchBar.delegate = self;
[self.collectionView addSubview:self.searchBar];
[self.collectionView setContentOffset:CGPointMake(0, 44)];
}
- (void) viewWillAppear:(BOOL)animated{
// to show search bar
[self.collectionView setContentOffset:CGPointMake(0, 0)];
// to hide search bar
[self.collectionView setContentOffset:CGPointMake(0, 44)];
}
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:YES animated:YES];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[searchBar setText:#""];
[searchBar setShowsCancelButton:NO animated:YES];
[searchBar resignFirstResponder];
}
On an iPad application, I want to be able to have multiple buttons in the top bar of a popover. I'm launching it like this:
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
pop = [[UIPopoverController alloc] initWithContentViewController:nc];
[pop presentPopoverFromRect:CGRectInset([tableView rectForRowAtIndexPath:indexPath], 10, 10)
inView:tableView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
pop.delegate = self;
[nc release];
In the viewDidLoad I want to set the titleView to contain multiple UIBarButtonItems. This is ok on a normal UINavigationController but I need to be able to do this and keep the custom style of the navigation bar on the popover.
I have tried setting the rightBarButtonItem to have a toolbar that contains buttons, but they take the format of the toolbar, which itself will not take the format/style of the popover.
It's a bit hackish, but you can create a truly transparent UIToolbar by subclassing and overriding drawRect: with an empty method. This will still draw the UIBarButtonItems on the toolbar, but not the toolbar itself.
Then, as Nils describes, you can create a bar button item out of the custom toolbar instance and add it as the rightBarButtonItem.
Why you don't use a custom UIView with a UIToolbar or UINavigationBar instead of UIPopoverController?
The effect, is the same!
First you need to set a delegate to the UINavigationController and then implement the nabigationController:willShowViewController:animated: method. In this method you can adjust the left and right bar button items.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
viewController.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
initWithTitle:#"Image Source"
style:UIBarButtonItemStylePlain
target:self
action:#selector(cancelPressed)] autorelease];
}
I had the same problem, and here is what I did :
UIBarButtonItem *uiBarRefresh = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(forcerefresh)];
UIBarButtonItem *uiBarCurl = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPageCurl target:self action:#selector(showlist)];
UIToolbar_transparent* tools = [[UIToolbar_transparent alloc] initWithFrame:CGRectMake(0, 0, 133, 44.01)];
tools.barStyle = UIBarStyleBlackTranslucent;
tools.translucent = YES;
tools.backgroundColor = [UIColor clearColor];
tools.tintColor = self.navigationController.navigationBar.tintColor;
[tools setItems:[NSArray arrayWithObjects:flexItem,uiBarRefresh,uiBarCurl,nil] animated:NO];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:tools];
This way you avoid the dull grey background, the pesky white underline, and you can completely customize how you want them positioned, by using fixed or flex spacings.
Best of luck with your project :]