22

I add UISearchBar above UINavigationBar and set UIsearchbar showsCancelButton YES, work fine in iOS6 but in iOS7 not showing cancel button. I used below code snippet

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 600, 44)];
searchBar.showsCancelButton = YES;
searchBar.translucent = NO;
[searchBar setTintColor:[UIColor redColor]];
searchBar.backgroundColor = [UIColor yellowColor];
[self.navigationController.navigationBar   addSubview:searchBar];
JackYi
  • 245
  • 1
  • 3
  • 5

7 Answers7

44

For some reason iOS7 does not show the cancel button when added to a navigation bar. This also happens if you try setting it as the titleView of a navigationItem.

You can circumvent this problem by wrapping the UISearchBar in another UIView first. Here's how I do it as a titleView:

UISearchBar *searchBar = [UISearchBar new];
searchBar.showsCancelButton = YES;
[searchBar sizeToFit];
UIView *barWrapper = [[UIView alloc]initWithFrame:searchBar.bounds];
[barWrapper addSubview:searchBar];
self.navigationItem.titleView = barWrapper;
Rodskjegg
  • 489
  • 5
  • 2
  • I've encountered the same problem and tried your solution. However, the search bar picks up a different style and the size isn't correct. Have you further developed this solution and fixed the details? – Codo Sep 28 '13 at 16:04
  • Wrapping the UISearchBar in a UIView before placing in the UINavigationBar worked for me. I am, however, adding it as a subview instead of the titleView. – Stephen Sep 28 '13 at 22:44
  • 2
    It's true the style of the bar changes and doesn't fit too well with the nav.bar. I did searchBar.searchBarStyle = UISearchBarStyleMinimal which suits my needs at least. – Rodskjegg Sep 29 '13 at 09:38
  • For me, it seems to work except that i cant see the search bar at all. If i click in that area the keyboard and search results come up fine, but i cant see any of what im typing.. – Ken Koch Oct 23 '13 at 14:51
  • If your app enables both portrait and landscape mode, then it won't recalculate the size properly when you switch orientations. This is where auto-layout would be helpful, but it would involve some finagling with the titleView property, which auto adjusts size when an item is set. So annoying. I ended up just creating my own cancel button and placing it as the rightBarButtonItem. – ArtSabintsev Nov 11 '14 at 20:20
  • the accepted answer is a good start, but as people say, it messes up the style and look. @Rodskjegg style line plus wrapping the search bar in a uiview thats added as a subview to nav bar worked for me – skinsfan00atg Mar 03 '15 at 15:39
6

I had similar problem, on iPhone search bar with cancel button show well, but on iPad the cancel button wasn't shown. Wrapping the UIsearchBar to UIView like @Rodskjegg throw style issue. On iPad UIsearchBar setting it as the titleView of a navigationItem and add UIBarButtonItem to setRighttBarButtonItem as UIBarButtonSystemItemCancel.

    [self.navigationItem setLeftBarButtonItem:Nil animated:YES];
    self.navigationItem.titleView = self.searchBar;

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) 
    {
        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(searchBarCancelButtonClicked:)];

        [self.navigationItem setRightBarButtonItem: cancelButton animated:YES];
    }
    else {
        [self.navigationItem setRightBarButtonItem: nil animated:YES];
    }
vcalfa
  • 156
  • 1
  • 6
  • I also had some style issues (searchbar was to big initially and did not resize correctly on interface rotation) and solved by adding a bar button myself .. not the cleanest approach but anyway. Thanks for the answer – Sebastian Boldt Nov 24 '15 at 10:48
  • This is the least hacky solution IMO. It worked better for me than the `addSubview` method above without any jarring frame/ animation issues. Great solution! – manderson Jun 17 '16 at 17:37
4

Since iOS 7 you can just set the property displaysSearchBarInNavigationBar to YES on the UISearchDisplayController to automatically get a UISearchbar in the NavigationBar.

itsji10dra
  • 4,603
  • 3
  • 39
  • 59
kohaxun
  • 49
  • 2
4

Yes In iOS 7 button is located on the screen, but it's title could be invisible My solution was to set Search Style to "Minimal" and choose bar tint colour for "Cancel" text colour in IB

enter image description here

And the Result in a simulator :

enter image description here

codercat
  • 22,873
  • 9
  • 61
  • 85
David
  • 1,061
  • 11
  • 18
3

I ran into the same problem, here's my solution, hope this helps.

Some further explanation: I found out that sending setShowsCancelButton:animated: to the searchBar, it just works like magic. And the cleanest way to add a searchBar to navigation bar is self.navigationItem.titleView = self.searchBar; The appropriate timing for calling setShowsCancelButton:animated: is in searchBarTextDidBeginEditing: and searchBarTextDidEndEditing: delegate methods, so remember to set self to be the delegate of searchBar.

- (void)viewDidLoad
{
    self.navigationItem.titleView = self.searchBar;
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    [searchBar setShowsCancelButton:YES animated:YES]; 
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    [searchBar setShowsCancelButton:NO animated:YES];
}
廖維平
  • 31
  • 2
  • 1
    Code-only answers are typically frowned upon on SO. You should try adding some explanation as to *why/how* your code works. – codeMagic Aug 21 '14 at 20:10
  • 2
    Answer edited to give more explanation, I thought the code itself is pretty self-explanatory, don't be harsh on me, thanks. – 廖維平 Aug 21 '14 at 21:25
  • 1
    I wasn't harsh on you. As your first answer on SO, I simply commented that an explanation makes for a much better answer. It may seem self explanatory to you and many others but it may not be for someone else with the same problem in the future. – codeMagic Aug 21 '14 at 21:44
2

I had the same problem, on iPhone the search cancel was shown well, but on iPad it didn't.

The workaround of wrapping the UISearchBar in another UIView didn't work well for me since it had different appearance and wrong width on rotation.

My solution is a simple one - use search WITHOUT cancel, and add cancel as UIBarButtonItem.

Tal Haham
  • 1,500
  • 12
  • 16
0

Implement the search bar delegate and use this:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    searchBar.showsCancelButton = YES;
}