Cancel button in search bar don´t work in iOS 7 when search bar is initially hidden.
I follow this tutorial to create a search bar in tableview:
raywenderlich tutorial
There are a example project in this tutorial, is better use this project than my explanation :)
In iOS 5 and 6 works fine.
I have reviewed all delegates.
There are two possibilities. The first is to press the button when the bar is hidden, the second is to press the button when the bar is displayed (moving the table down with a gesture you can see the search bar)
If search bar is hidden initially cancel button don´t work, it don't call calcel delegate method:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
Sorry I can not explain it better.
Thanks
I googled all over internet and couldn't find a solution. so i changed the UItableview behaviour.
instead of [searchBar becomeFirstResponder]; I scroll down the tableview.
- (IBAction)goToSearch:(id)sender {
scroll down to show the table.
// CGRect newBounds = self.tableView.bounds;
// newBounds.origin.y =0;
//
// self.tableView.bounds = newBounds;
//[searchBar becomeFirstResponder];
CGPoint contentOffset=self.tableView.contentOffset;
contentOffset.y=0;
[self.tableView setContentOffset:contentOffset animated:YES];
}
in my ViewDidload:
// CGRect newBounds = self.tableView.bounds;
// newBounds.origin.y = newBounds.origin.y + searchBar.bounds.size.height;
// self.tableView.bounds = newBounds;
CGPoint contentOffset=self.tableView.contentOffset;
contentOffset.y=self.tableView.bounds.origin.y + searchBar.bounds.size.height;
self.tableView.contentOffset=contentOffset;
If found for some reasons, in iOS 7 , change table view bounds cause search bar to disappear.
Hope that helps.
That code work for me on iOS7:
- (IBAction)goToSearch:(id)sender {
[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
[candySearchBar becomeFirstResponder];
}
put this code in your project it will work i have tested and it is working correctly
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchbar
{
[searchbar resignFirstResponder];
for (UIView *possibleButton in searchbar.subviews)
{
if ([possibleButton isKindOfClass:[UIButton class]])
{
UIButton *cancelButton = (UIButton*)possibleButton;
cancelButton.enabled = YES;
break;
}
}
}
This problem seems to come from the new behaviour of the translucent property in a navigation bar.
Since iOS 7 navigation bars are translucent by default. And it looks like it's overlapping the search bar when you display it after pressing a button.
Try to set in your controller:
float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (osVersion >= 7.0)
{
self.navigationController.navigationBar.translucent = NO;
}
This should quickly solve the problem.
But I think for a better fix you should see the iOS 7 transition guide where they explain how to handle translucent navigation bars.
Hope that helps.
I assume you have set _searchBar.delegate = self and implemented UISearchBarDelegate in your class.
This is how you do it:
- (void) searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
[searchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ // called when cancel button pressed
searchBar.text = nil;
//hide cancel button
[_searchBar setShowsCancelButton:NO animated:YES];
[searchBar resignFirstResponder];
}
Related
I have a hidden searchBar in a tableView header:
- (void)viewWillAppear:(BOOL)animated {
CGRect newBounds = self.tableView.bounds;
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.tableView.bounds = newBounds;
}
I also have a magnifying-glass icon button that reveals the search bar:
- (IBAction)showSearchBar:(id)sender {
[self.searchDisplayController setActive:YES animated:YES];
[self performSelector:#selector(showKeyboard) withObject:nil afterDelay:0.1];
}
Problem is, when I pull down the table (to reload data) - it also shows the search bar.
I only want the searchBar to become visible when the magnifying-glass icon gets tapped.
I am not really sure, how to address this problem?
Am I hiding it the wrong way in the first place?
Thanks,
Added a screenshot to make my question more clear:
searchbar appears when pulling down
I don't tried that out, but I can image that you just have to hide it. for example:
[[self.searchDisplayController view] setHidden:YES]
I am using following code for adding UISearchBar in iOS7 and UISearchBar appearance is fine.But problem is when press cancel button on UISearchBar then UIKeyboard appeared.Why its happen?Please help me.
CGRect searchFrame = CGRectMake(self.view.bounds.origin.x, 64, self.view.bounds.size.width, 44.0f);
self.mySearchBar = [[UISearchBar alloc]initWithFrame:searchFrame];
self.mySearchBar.delegate = self;
self.mySearchBar.searchBarStyle = UISearchBarStyleDefault;
self.mySearchBar.placeholder = #"search items;
self.mySearchBar.showsCancelButton = YES;
[self.view addSubview:self.mySearchBar];
Implement the searchBarCancelButtonClicked: UISearchBarDelegate method. If you want the keyboard to go away you would do something like:
- (void) searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
I got your issue now.
When there is not text entered at that time cancel button will be disabled. So if you try to press it than it will consider SearchBar text area & Keyboard will appear.
While you enter the text than Cancel button will be active & than it will work.
Hope you'll get the solution from this.
I want to use a search bar button in a navigation bar to show a search bar just like Apple do in the Calendar app. The cancel button would dismiss the search bar and return the navigation bar to its former state, bar buttons, title, etc.
Using the iOS 7 property:
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
puts the search bar into the navigation bar just fine. My problem is trying to have it appear conditionally on the press of a bar button. I've tried firing this line from my button's action but no go. I've tried setActive:Animated: on the searchDisplayController
self.searchDisplayController.active = YES;
but no luck either. Any ideas or help would be appreciated.
I'm not sure if you notice, but on the Apple's calendar app when you press the search icon, it open a new UITableView with search bar. If this is what you want to do, you will have a create a UIViewController with a UITableView and a UISearchBar which inside that tableView you will be filtering the content.
If I was you, I will just hide the UISearchBar and call it whenever is needed with the button to show up.
This might work as well. Just give it a try and let me know:
In your viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
// scroll search bar out of sight
CGRect newBounds = self.tableView.bounds;
if (self.tableView.bounds.origin.y < 44) {
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.tableView.bounds = newBounds;
}
// new for iOS 7
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:0 animated:YES];}
Now that is hidden, call this to hide it again when the search is done:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self viewWillAppear:YES];
}
and to show the searchBar with a button, then:
- (IBAction)displaySearchBar:(id)sender {
// makes the search bar visible
[self.searchBar becomeFirstResponder];
}
In iOS 8 you can simply present a UISearchController and you will get the same animation as Calendar.app. Check out Apple's UICatalog sample code for an example.
I have an iOS 7 application in XCode 5.0 that exhibits some strange behavior when tapping the search bar (UISearchBar).
My application has a Navigation Controller, and a Tab Bar Controller. Here is an example of what my Main.Storyboard looks like:
[Navigation Controller] -> [Tab Bar Controller] -> [Tab Item #1]
|
-------------> [Tab Item #2]
Each [] is a view controller
When I launch my application, I see the Tab Item 1 with the UISearchBar as shown in the screenshot below:
When I tap the UISearchBar, the search bar slides up to the top of the screen, but the Navigation Bar does not hide, and the view does not "slide up". This causes the app to look like this:
When I delete the Tab Bar Controller from the storyboard and connect the Navigation Controller directly to Tab Item #1 the Navigation Bar hides as expected.
How can I make the Navigation Bar hide when tapping the Search Bar? For an example of the functionality I am looking to reproduce, click the search bar under the "Contacts" tab of the default iOS7 "Phone" application.
For swift developers:
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
navigationController?.setNavigationBarHidden(true, animated: true)
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
navigationController?.setNavigationBarHidden(false, animated: true)
}
This will hide the navigation bar while search bar is active and show it again when search bar is inactive.
You can use the UISearchBar delegate methods to decide when to move the navigationbar out of the screen.
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
[UIView animateWithDuration:0.2 animations:^{
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
double yDiff = self.navigationController.navigationBar.frame.origin.y - self.navigationController.navigationBar.frame.size.height - statusBarFrame.size.height;
self.navigationController.navigationBar.frame = CGRectMake(0, yDiff, 320, self.navigationController.navigationBar.frame.size.height);
}];
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
[UIView animateWithDuration:0.2 animations:^{
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
double yDiff = self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height + statusBarFrame.size.height;
self.navigationController.navigationBar.frame = CGRectMake(0, yDiff, 320, self.navigationController.navigationBar.frame.size.height);
}];
}
The following line will hide the navigation bar animatedly on activating search bar.
self.searchController.hidesNavigationBarDuringPresentation = true
You can set the top bar in the navigation controller for the list, to none and then add this to your tabBarController code:
self.navigationController.navigationBar.translucent= NO;
In the viewDidLoad method
You can do it with UISearchDisplayController method;
-(void)searchDisplayControllerWillBeginSearch:(mySearchDisplayController *)controller
{
self.searchResultsDataSource = self;
self.searchResultsTableView.delegate = self;
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
{
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
[UIView animateWithDuration:0.01 animations:^{
for (UIView *subview in self.searchBar.subviews)
subview.transform = CGAffineTransformMakeTranslation(0, statusBarFrame.size.height);
}];
}
}
-(void)searchDisplayControllerWillEndSearch:(mySearchDisplayController *)controller
{
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
{
[UIView animateWithDuration:0.01 animations:^{
for (UIView *subview in self.searchBar.subviews)
subview.transform = CGAffineTransformIdentity;
}];
}
}
Don't forget create a new class as a type of UISearchDisplayController and implement that code in it.
I solved the problem by adding constraint on Search Bar to Top Layout Guide and set its value to 0 and added a vertical spacing constraint to Search Bar and setting its value to 0;
I realize that this is probably too late to help you, but I ran into the same issue today!
I solved it by fixing the constraints of the search bar. Make sure the search bar has a constraint of 0px for its immediate top neighbor (the nav bar). Also make sure the tableview below the search bar has a constraint of 0px for its immediate top neighbor (the search bar).
Not sure of the exact problem you were facing, but that fixed it for me.
I write UISearchBar in my TopBar.m like this:
_tempSearchBar =[[UISearchBar alloc]initWithFrame:CGRectMake(44, 0, 320 - 44, 43)];
_tempSearchBar.barStyle=UIBarStyleDefault;
_tempSearchBar.placeholder=#"搜索";
[self addSubview:_tempSearchBar];
the result is like this, it is right.
and then I write UISearchDisplayController in another class like this:
_topBar.tempSearchBar.delegate = self;
_searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:_topBar.tempSearchBar contentsController:self];
[_searchDisplayController setDelegate:self];
[_searchDisplayController setSearchResultsDataSource:self];
the UISearchBarDelegate is like this:
#pragma mark -
#pragma mark UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[_searchDisplayController setActive:YES animated:YES];
}
when I click the UISearchBar , it show like this , the searchBar`s frame is changed.why?
when I cancel the UISearchDisplayController it is like this :
why the frame is changed? The width is changed from 320-44 to 320 by the UISearchDisplayController?
thanks.
UISearchDisplayController expands the search bar to the width of its superview. The simplest solution that I have found is to place the search bar inside another UIView that has the width I am looking for.
The searchBar's frame is changed by the UIKit, so I changed the searchBar's frame back myself.
I changed the searchBar's frame in the below delegate.
One is UISearchBar's delegate:
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
[searchBar setFrame:CGRectMake(44, 0, 320 - 44, 43)];
}
Another is UISearchDisplayController's delegate:
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller{
[controller.searchBar setFrame:CGRectMake(44, 0, 320 - 44, 43)];
[self.searchDisplayController.searchResultsTableView setDelegate:self];
}
It can work and I can get the right frame, but when I click the searchBar it will shake a little.
It is not the best way to do it, but it can work. Does anyone have a better method?
Update:
I have debugged the UISearchBar and UISearchDisplayController for a few hours, but it has a little bug: When I endEditing the searchBar's width will become 320px, and then will become my width. I can not change the cancelButton's background color. So I wrote a custom SearchDisplayController, with a UISearchBar property and a UITableView property. It works well for me.
Call the delegate method
- (void) searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
[controller.searchBar setFrame:CGRectMake(0,31, 320 , 43)];
[self.searchDisplayController.searchResultsTableView setDelegate:self];
}
You can handle the cancel button of searchBar using - (void)setShowsCancelButton:animated:
If you do not want to show cancel button (as cancel button will change the frame of searchBar)
just write this in delegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[searchBar setShowsCancelButton:NO animated:YES];
}
Updated:
An only possible solution seems to be finding the cancel button from SearchBar view hierarchy and hiding it.
for (UIView *possibleButton in searchBar.subviews)
{
if ([possibleButton isKindOfClass:[UIButton class]])
{
UIButton *cancelButton = (UIButton*)possibleButton;
cancelButton.hidden = YES;
break;
}
}