I have a search bar as a title view for my navigation bar.
And it looks like this, the way I want it to look like:
But when I tap on it, it just slides to top and becomes inaccessible
Here is the code I used to configure it:
- (void)configureSearchBar
{
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchBar.delegate = self;
self.navigationItem.titleView = self.searchController.searchBar;
}
Is there any way to fix this kind of problem?
self.searchController.hidesNavigationBarDuringPresentation = NO
Adding this line has solved this problem or me. The reason of this problem was that my search bar was set as a title view for my navigation bar and the property hidesNavigationBarDuringPresentation was set to YES by default. Setting this property to NO solves this kind of problem.
Related
How can I show a UISearchBar in the NavigationBar?
I can't figure out how to do this.
Your help is very much appreciated.
To put searchBar into the center of navigationBar:
self.navigationItem.titleView = self.searchBarTop;
To put searchBar to the left/right side of navigationBar:
UIBarButtonItem *searchBarItem = [[UIBarButtonItem alloc] initWithCustomView:searchBar];
self.navigationItem.rightBarButtonItem = searchBarItem;
As of iOS 7, the UISearchDisplayController supports this by default. Set the UISearchDisplayController's displaysSearchBarInNavigationBar = YES to get this working easily.
Per the documentation:
Starting in iOS 7.0, you can use a search display controller with a navigation bar (an instance of the UINavigationBar class) by configuring the search display controller’s displaysSearchBarInNavigationBar and navigationItem properties.
As one commenter noted, using searchDisplayController.displaysSearchBarInNavigationBar = true ends up hiding any existing left/right bar button items.
I've found two different ways of adding a searchBar to a navigationBar using iOS7's new property on searchDisplayController.
1) Nib Based Approach
If you're using a .xib, you can set a User Defined Runtime Attribute for this value and for whatever reason, the leftBarButtonItem stays in tact. I have not tested it with a rightBarButtonItem.
2) Code (Timing Matters)
If you want to implement in code, timing seems to matter. It seems that you must add the searchBar to the navigationBar first, then set your barButtonItem.
- (void)viewDidLoad
{
...
self.searchDisplayController.displaysSearchBarInNavigationBar = true;
self.navigationItem.leftBarButtonItem = [UIBarButtonItem new];
...
}
Check out Apple's UICatalog sample code. It shows how to use the new UISearchController in three different ways: modally, in nav bar, and below the navigation bar.
Objective C code snippet for UISearchBar in NavigationBar
- (void)viewDidLoad {
UISearchController *searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
if (#available(iOS 11.0, *)) {
self.navigationItem.searchController = searchController;
} else {
self.navigationItem.titleView = searchController.searchBar;
}
}
Read more here
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 trying to use the new UISearchController from iOS 8, and embed its UISearchBar in my UINavigationBar. That's easily done as follows:
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.delegate = self
searchController.searchBar.delegate = self
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.titleView = searchController.searchBar
But when I add the scope buttons:
searchController.searchBar.showsScopeBar = true
searchController.searchBar.scopeButtonTitles = ["Posts, Users, Subreddits"]
It adds the buttons behind the UISearchBar and obviously looks very odd.
How should I be doing this?
You're bumping into a "design issue" where the scopeBar is expected to be hidden when the searchController is not active.
The scope bar buttons appear behind (underneath) the search bar since that's their location when the search bar becomes active and animates itself up into the navigation bar.
When the search is not active, a visible scope bar would take up space on the screen, distract from the content, and confuse the user (since the scope buttons have no results to filter).
Since your searchBar is already located in the titleView, the (navigation and search) bar animation that reveals the scope bar doesn't occur.
The easiest option is to locate the search bar below the
navigation bar, and let the searchBar animate up into the title
area when activated. The navigation bar will animate its height,
making room to include the scope bar that was hidden. This will all
be handled by the search controller.
The second option, almost as easy, is to use a Search bar button
icon, which will animate the searchBar and scopeBar down into
view over the navigation bar.
- (IBAction)searchButtonClicked:(UIBarButtonItem *)__unused sender {
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.definesPresentationContext = YES;
self.searchController.searchBar.scopeButtonTitles = #[#"Posts", #"Users", #"Subreddits"];
[self presentViewController:self.searchController animated:YES completion:nil];
}
If you want the searchBar to remain in the titleView, an animation
to do what you want is not built in. You'll have to roll your own
code to handle the navigationBar height change and display your own
scope bar (or hook into the internals, and animate the built-in
scopeBar down and into view).
If you're fortunate, someone else has written willPresentSearchController: code to handle the transition you want.
If you want to always see a searchBar and scopeBar, you'll probably have to ditch using the built-in scopeBar, and replace it with a UISegmentedControl which the user will always see, even when the search controller is not active.
Update:
This answer suggested subclassing UISearchController to change its searchBar's height.
I have an issue with a search bar that behaves in a strange way when it becomes a firstResponder and when it resigns.
The search bar is added as the header of a table view
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 44.0f)];
self.searchBar.translucent = NO;
self.searchBar.barTintColor = [UIColor grayColor];
self.tableView.tableHeaderView = self.searchBar;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar
contentsController:self];
self.searchController.searchResultsDataSource = self;
The view controller is set a left panel of JASidePanelController and it hides the center panel when the keyboard shows or hides :
- (void)keyboardWillAppear:(NSNotification *)note
{
[self.sidePanelController setCenterPanelHidden:YES
animated:YES
duration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
self.searchBar.showsCancelButton = YES;
}
- (void)keyboardWillDisappear:(NSNotification *)note
{
[self.sidePanelController setCenterPanelHidden:NO
animated:YES
duration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
self.searchBar.showsCancelButton = NO;
}
Normal state
When the search bar becomes a firstResponder it either moves about a point up or point down randomly
And When the search bar resigns it animates up to reach the window origin and then back to its natural frame
Here is a sample project reproducing the bug.
EDIT :
As per #kwylez suggestion, the unwanted animation that the search bar makes when it resigns can be avoided by:
self.searchBar.clipsToBounds = YES;
I solved this issue by creating a UIView with ClipBounds sets to YES and then add subview the searchbar inside it.
Then include it in tableview header. its working now.
Thanks
You initialize a search display controller with a search bar and a view controller responsible for managing the data to be searched. When the user starts a search, the search display controller superimposes the search interface over the original view controller’s view and shows the search results in its table view.
customized your searchbar view
Fixed - UISearchBar-bug-master
I traced the issue to the function "_layoutSidePanels" in the JASidePanelController.
In your app delegate, I commented out the following code and it seems to fix the grey view growing and shrinking.
rootViewController.shouldResizeLeftPanel = YES;
If you follow the code through, when the searchbar is selected you call setCenterPanelHidden, which subsequently calls _layoutSidePanels, which runs the following code:
if (self.leftPanel.isViewLoaded) {
CGRect frame = self.leftPanelContainer.bounds;
if (self.shouldResizeLeftPanel) {
frame.size.width = self.leftVisibleWidth;
}
self.leftPanel.view.frame = frame;
}
Changing the frame of the sidepanel seems to be the cause, and as I said commenting that code out fixes the issue on my end.
Edit: Also at first it seemed like the search bar was moving up and down a point, but upon further inspection it appears that it is always slightly underneath the navigation bar, but you don't notice it until you select the searchbar and the rest of the view "greys" out, so that little space that was white between the blue nav bar and light grey search bar becomes dark grey like the rest of the tableview below.
Edit #2: Took me a while, but I managed to figure out where the heck that grey mask was coming from. Your UISearchDisplayController is what is responsible for the greyish background that appears when the search bar becomes first responder, and when I removed the following two lines of code the issue you were seeing went away:
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchController.searchResultsDataSource = self;
Doing this was just to demonstrate the cause of the issue, but removing those lines of code disable whatever functionality you were going to gain from using the search display controller. I don't know exactly what you're hoping to do, so I can't really give you any advice about how to proceed, but hopefully I've pointed you in the right direction as to the causes!
How can I show a UISearchBar in the NavigationBar?
I can't figure out how to do this.
Your help is very much appreciated.
To put searchBar into the center of navigationBar:
self.navigationItem.titleView = self.searchBarTop;
To put searchBar to the left/right side of navigationBar:
UIBarButtonItem *searchBarItem = [[UIBarButtonItem alloc] initWithCustomView:searchBar];
self.navigationItem.rightBarButtonItem = searchBarItem;
As of iOS 7, the UISearchDisplayController supports this by default. Set the UISearchDisplayController's displaysSearchBarInNavigationBar = YES to get this working easily.
Per the documentation:
Starting in iOS 7.0, you can use a search display controller with a navigation bar (an instance of the UINavigationBar class) by configuring the search display controller’s displaysSearchBarInNavigationBar and navigationItem properties.
As one commenter noted, using searchDisplayController.displaysSearchBarInNavigationBar = true ends up hiding any existing left/right bar button items.
I've found two different ways of adding a searchBar to a navigationBar using iOS7's new property on searchDisplayController.
1) Nib Based Approach
If you're using a .xib, you can set a User Defined Runtime Attribute for this value and for whatever reason, the leftBarButtonItem stays in tact. I have not tested it with a rightBarButtonItem.
2) Code (Timing Matters)
If you want to implement in code, timing seems to matter. It seems that you must add the searchBar to the navigationBar first, then set your barButtonItem.
- (void)viewDidLoad
{
...
self.searchDisplayController.displaysSearchBarInNavigationBar = true;
self.navigationItem.leftBarButtonItem = [UIBarButtonItem new];
...
}
Check out Apple's UICatalog sample code. It shows how to use the new UISearchController in three different ways: modally, in nav bar, and below the navigation bar.
Objective C code snippet for UISearchBar in NavigationBar
- (void)viewDidLoad {
UISearchController *searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
if (#available(iOS 11.0, *)) {
self.navigationItem.searchController = searchController;
} else {
self.navigationItem.titleView = searchController.searchBar;
}
}
Read more here