Right, to begin my question, here's some screenies of the problem already solved by the Spotify app:
Spotify's Step 1: Standard UISearchBar not in editing mode.
Step 1 http://i49.tinypic.com/wbtpwi.png
Spotify's Step 2: UISearchBar now in editing mode. Search term entered. Cancel button slides in from the right, and the clear button (grey x) appears.
Step 2 http://i45.tinypic.com/161kbvp.png
Spotify's Step 3: Cancel button pressed; keyboard slides out and the search bar is no longer in editing mode. Search term remains and the grey x button is now hidden.
Step 3 http://i46.tinypic.com/20utv9v.png
At present, the following code fires off when my cancel button is pressed:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
[searchBar setShowsCancelButton:NO animated:YES];
}
Which results in:
My Step 3: Search bar now not in editing mode. Cancel button and keyboard has slid out. Search term remains but so does the grey x.
Problem http://i46.tinypic.com/rlm4w5.png
So, my question is this: given that -resignFirstResponder
(and -endEditing:
, FYI) does not hide the grey x button when a search bar has had text entered into it, how does one hide it?
Thanks again, friends.
I'm building upon the previous answers because I started seeing crashes on iOS 7.1 unless I made the following change. I added an additional call to
respondsToSelector
for each view to make sure thatsetClearButtonMode:
can be called. I observed an instance ofUISearchBar
getting passed in, which seems to conform to theUITextInputTraits
protocol yet does not have thesetClearButtonMode:
selector, so a crash occurred. An instance ofUISearchBarTextField
also gets passed in and is the actual object for which to callsetClearButtonMode:
.There's a better way than any of the answers here, and you don't have to use private APIs or traverse subviews to do it.
UISearchBar has a built-in API for doing this:
[UISearchBar setImage:forSearchBarIcon:state]
The SearchBar icon key you want is UISearchBarIconClear, and you want the UIControlStateNormal state. Then give it a clear image for the image, and you're done.
So, it should look like this:
Accepted answer does not work on iOS7+, here is the modified version as a Swift extension
Usage
The problem is that UISearchBar doesn't expose it's text field, and manages the properties on the text field itself. Sometimes, the values of the properties aren't what you want.
For instance, in my own app, I wanted the keyboard style for my search bar to use the transparent alert style.
My solution was to walk through the subviews of the search bar until you find the text field. You should then be able to set the
clearButtonMode
property, using something likeUITextFieldViewModeWhileEditing
as a parameter.This should make it so that the clear button is only shown while the text field is editing.
You want to do this on
viewDidLoad
or something early, so it's set before you start using it (but after the search bar is initialised.You need to get the textField of the Search Bar
use in - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar method.