Detecting when clear is clicked in UISearchBar (X button)

When conforming to UISearchBar delegate we do not get a notification when user clicks the clear text button in the UISearchBar. However, UISearchBar has a subview of type UITextField, and if we conform to UITextFieldDelegate we do get a call when clear text button is clicked in form of:

- (BOOL)textFieldShouldClear:(UITextField *)textField

The problem is that when we conform to UISearchBar protocol, we do not conform to the underlying UITextField’s delegate. What we have to do is set the delegate ourselfs in for example viewDidLoad method. (if you do not have an outlet to the UISearchBar create it, and call it searchBar).

In your header (.h) file do not forget to conform to delegates.
<UISearchBarDelegate, UITextFieldDelegate>

- (void)viewDidLoad {
  //find the UITextField view within searchBar (outlet to UISearchBar)
  //and assign self as delegate
  for (UIView *view in searchBar.subviews){
    if ([view isKindOfClass: [UITextField class]]) {
      UITextField *tf = (UITextField *)view;
      tf.delegate = self;
      break;
    }
  }
}

- (void)searchBarCancelButtonClicked:(UISearchBar *) aSearchBar {
	[aSearchBar resignFirstResponder];
}

- (BOOL)textFieldShouldClear:(UITextField *)textField {
    //if we only try and resignFirstResponder on textField or searchBar,
    //the keyboard will not dissapear (at least not on iPad)!
    [self performSelector:@selector(searchBarCancelButtonClicked:) withObject:self.searchBar afterDelay: 0.1];
    return YES;
}

Advertisements
  1. #1 by Joshua Kendall on June 7, 2011 - 5:09 pm

    Thank you for posting this, I was looking everywhere for a solution to this and all I could find were solutions that attempted to check if the searchbar was the first responder and if it wasn’t to set it as it and then resign it, none of which actually wanted to work. It’s so simple I can’t believe it didn’t occur to me to set the delegate of the SearchBar’s TextField.

    • #2 by Ladislav Klinc on June 8, 2011 - 9:11 am

      Hey,

      great to see that this helped you out…it was the problem I had so I said to myself there’s gotta be someone out there with the same problem 🙂

      If you need any help or beta testing before release let me know!

      Ladislav

  2. #3 by flizit on July 14, 2011 - 3:31 pm

    Thanks for your post. This helped me as well.
    I had some code already iterating through the searchBar to customize the background.
    Had to take out the break statements in both to make them work, else one or the other will be skipped as the searchBar subviews are iterated through.

  3. #4 by xspotlivin on November 23, 2011 - 5:14 am

    My searchBar has no subviews when my viewDidLoad methods executes ([searchBar.subviews count] returns 0). How is this possible? (It is being linked in via IBOutlet.)

    • #5 by xspotlivin on November 23, 2011 - 5:25 am

      Nvm. The code existed but I never actually linked it from IB. Rookie mistake.

  4. #6 by Federico Cappelli (@federicokappe) on January 6, 2012 - 2:20 pm

    great solution! tnx!

  5. #7 by Federico Cappelli (@federicokappe) on January 6, 2012 - 2:31 pm

    ups… a “little” problem, after i set the UITextField Delegate, the searchbar never more fire the searchBarShouldBeginEditing delegate, if i comment the code:

    for (UIView *view in self.searchBar0.subviews)
    {
    if ([view isKindOfClass: [UITextField class]]) {
    UITextField *tf = (UITextField *)view;
    tf.delegate = self;
    tf.tag = 1000;
    break;
    }
    }

    the uisearchbar delegate back to work properly (Xcode 4.2 ios 5.0.1)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: