HurkNburkS
HurkNburkS

Reputation: 5510

Hide UISearchBar clear text button

I would like to know how to hide or not display the UISearchBar cross that appears in the textField fo the UISearchBar

I have tried using this

filterSearchBar.showsCancelButton = NO;

However this is an actual cancel button not the small grey cross, so I would like to know if there is an equivalent for the small grey button that shows in the UISearchBar.

Upvotes: 16

Views: 22392

Answers (15)

Anurag Bhakuni
Anurag Bhakuni

Reputation: 2439

Swift 5

Just add a single line below

searchBar.searchTextField.clearButtonMode = .never

Upvotes: 5

Swift 5

Tested on iOS 13

One liner working for me:

searchBar.searchTextField.clearButtonMode = .never

You can also set it to .whileEditing to have it displayed when the user is typing and then removed when the search bar loses focus.

Upvotes: 9

Hemang
Hemang

Reputation: 27050

thijsonline's answer in swift:

(UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self])).clearButtonMode = .never

Upvotes: 1

user4886069
user4886069

Reputation:

Converting Soto_iGhost's answer to Swift 4:

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {

    let textField: UITextField = searchBar.value(forKey: "_searchField") as! UITextField
    textField.clearButtonMode = .never
}

If you have an outlet of UISearchBar the you can write above code anywhere in your class.

Upvotes: 1

kishorer747
kishorer747

Reputation: 820

Based on @Gines answer, here is the Swift version:

func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
    guard let firstSubview = searchBar.subviews.first else { return }

    firstSubview.subviews.forEach {
        ($0 as? UITextField)?.clearButtonMode = .never
    }
}

Upvotes: 9

Maor
Maor

Reputation: 3430

Swift 3 solution :

extension UISearchBar{
    var textField : UITextField{
        return self.value(forKey: "_searchField") as! UITextField
    }
}

Usage :

searchBar.textField.clearButtonMode = .never

Upvotes: 3

thijsonline
thijsonline

Reputation: 1227

You can remove the clear text button for all UISearchBar instances:

[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]].clearButtonMode = UITextFieldViewModeNever;

Upvotes: 5

Charlton Provatas
Charlton Provatas

Reputation: 2274

Swift 4

Adding to Alexander's answer and block user interaction on clear button:

To hide button:

searchBar.setImage(UIImage(), for: .clear, state: .normal)

To disable user interaction on the clear button, simply subclass UISearchBar

class CustomSearchBar: UISearchBar {

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let view = super.hitTest(point, with: event)
        if view is UIButton {
            return view?.superview // this will pass-through all touches that would've been sent to the button
        }
        return view
    }
}

Upvotes: 8

Vahe Andreasyan
Vahe Andreasyan

Reputation: 21

Try this:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    UITextField *textField = [searchBar valueForKey:@"_searchField"];
    textField.clearButtonMode = UITextFieldViewModeNever;

}

Upvotes: 2

oskarsprima
oskarsprima

Reputation: 109

Swift 3, based on @Alexsander answer:

searchBar.setImage(UIImage(), for: .clear, state: .normal)

Upvotes: 5

Nemanja
Nemanja

Reputation: 453

Swift 2.3, based on @Alexsander answer:

searchBar.setImage(UIImage(named: "SearchClearIcon"), forSearchBarIcon: UISearchBarIcon.Clear, state: UIControlState.Highlighted)
searchBar.setImage(UIImage(named: "SearchClearIcon"), forSearchBarIcon: UISearchBarIcon.Clear, state: UIControlState.Normal)

Upvotes: 1

Bijendra Singh
Bijendra Singh

Reputation: 647

In Case of Swift 2.3 just use :

var searchBar = UISearchBar();
searchBar.frame = CGRectMake(0, 0, 00, 20))
for subview: UIView in (searchBar.subviews.first?.subviews)!
        {
            if (subview.isKindOfClass(UITextField) )
            {
                let textFieldObject = (subview as! UITextField)
                textFieldObject.clearButtonMode = .Never;
            }
        }

Upvotes: 1

Ginés SM
Ginés SM

Reputation: 233

I tried different solutions about this issue, even the one selected in this post, but they didn't work.

This is the way I found to solve this issue:

UIView *subview = [[searchBar subviews] firstObject]; //SearchBar only have one subview (UIView)

//There are three sub subviews (UISearchBarBackground, UINavigationButton, UISearchBarTextField)
for (UIView *subsubview in subview.subviews)
{
    //The UISearchBarTextField class is a UITextField. We can't use UISearchBarTextField directly here.
    if ([subsubview isKindOfClass: [UITextField class]])
    {
            [(UITextField *)subsubview setClearButtonMode:UITextFieldViewModeNever];
    }
}

Upvotes: 2

Alexander
Alexander

Reputation: 583

There's a better way to do this, and you don't have to use private APIs or traverse subviews to do it, so this solution is App Store safe.

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:

[searchBar setImage:clearImage forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];

Upvotes: 11

Soto_iGhost
Soto_iGhost

Reputation: 671

You need to get the textField of the Search Bar:

UITextField *textField = [searchBar valueForKey:@"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;

hope this help! =)

Upvotes: 37

Related Questions