42

I want my searchBar's tint color to be white (meaning the cancel button be white). The cursor is not visible when the tint color is white. Is there a way to set cursor color separately?

Ashish Awaghad
  • 2,822
  • 3
  • 24
  • 33

12 Answers12

67

Set your tint color to the color you want the cancel button to be and then use the UIAppearance Protocol to change the tint color on the text field to be the color you wish the cursor to be. Ex:

[self.searchBar setTintColor:[UIColor whiteColor]];                
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTintColor:[UIColor darkGrayColor]];
McFadden
  • 1,610
  • 1
  • 16
  • 19
17

Swift 3.0 and 4 version

searchController.searchBar.tintColor = .white        
UITextField.appearance(whenContainedInInstancesOf: [type(of: searchController.searchBar)]).tintColor = .black

Note that searchBar can't be optional.

Community
  • 1
  • 1
Fangming
  • 24,551
  • 6
  • 100
  • 90
13

If you're fond of functional, yet annoying one-liners in Swift, I got Benjamin's for loop down to this:

searchController.searchBar.tintColor = UIColor.whiteColor()

searchController.searchBar.subviews[0].subviews.flatMap(){ $0 as? UITextField }.first?.tintColor = UIColor.blueColor()
iantheparker
  • 239
  • 3
  • 11
8

Easiest in Swift 5:

    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).tintColor = .black
Joshua Hart
  • 772
  • 1
  • 21
  • 31
6

Compact Swift 2.0 solution using for-where syntax (no need to break loop):

// Make SearchBar's tint color white to get white cancel button.
searchBar.tintColor = UIColor.white()

// Loop into it's subviews and find TextField, change tint color to something else.
for subView in searchBar.subviews[0].subviews where subView.isKindOfClass(UITextField) {
        subView.tintColor = UIColor.darkTextColor()
}
Felipe Nuila
  • 61
  • 1
  • 3
5
searchBar.tintColor = [UIColor whiteColor];
searchBar.backgroundColor = [UIColor clearColor];
for ( UIView *v in [searchBar.subviews.firstObject subviews] )
{
    if ( YES == [v isKindOfClass:[UITextField class]] )
    {
        [((UITextField*)v) setTintColor:[UIColor blueColor]];
        break;
    }
}

enter image description here

Roman Solodyashkin
  • 799
  • 12
  • 17
5

This seemed to work for me in swift as well.

    searchController.searchBar.tintColor = UIColor.whiteColor()
    UITextField.appearanceWhenContainedInInstancesOfClasses([searchController.searchBar.dynamicType]).tintColor = UIColor.blackColor()
Eric Hodgins
  • 546
  • 1
  • 9
  • 14
4

For those looking to do the same in Swift, here is a solution I came accros after quite a lot of trouble :

override func viewWillAppear(animated: Bool) {
    self.searchBar.tintColor = UIColor.whiteColor()

    let view: UIView = self.searchBar.subviews[0] as! UIView
    let subViewsArray = view.subviews

    for (subView: UIView) in subViewsArray as! [UIView] {
        println(subView)
        if subView.isKindOfClass(UITextField){
            subView.tintColor = UIColor.blueColor()
        }
    }

}
Benjamin
  • 8,128
  • 3
  • 34
  • 45
3

I would just add an extension to UISearchBar with the following code.

extension UISearchBar {
    var cursorColor: UIColor! {
        set {
            for subView in self.subviews[0].subviews where ((subView as? UITextField) != nil) {
                subView.tintColor = newValue
            }
        }
        get {
            for subView in self.subviews[0].subviews where ((subView as? UITextField) != nil) {
                return subView.tintColor
            }
            // Return default tintColor
            return UIColor.eightBit(red: 1, green: 122, blue: 255, alpha: 100)
        }
    }
}
I make my mark
  • 841
  • 6
  • 13
3

iOS 9 and above

The easiest way to set a tintColor different for cancel button and textField, use this:

[self.searchBar setTintColor:[UIColor whiteColor]];
[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTintColor:UIColor.blueColor];
Adam Studenic
  • 2,115
  • 2
  • 25
  • 22
  • 1
    You are missing a [ at the start of your first line... Should be : [self.searchBar setTintColor:[UIColor whiteColor]]; – Peter Suwara Aug 16 '19 at 12:27
1

This is the easiest solution.

let textField = self.searchBar.value(forKey: "searchField") as! UITextField

    textField.tintColor = UIColor.white
  • `let textField = self.searchBar.value(forKey: "searchField") as? UITextField; textField?.tintColor = UIColor.white` avoids forced unwrapping and thereby any unwanted crashes. – idrougge Mar 14 '19 at 12:25
1

Here is a "functional" version of Felipe's answer (Swift 4.2)

// Make SearchBar's tint color white to get white cancel button.
searchBar.tintColor = .white

// Get the TextField subviews, change tint color to something else.
if let textFields = searchBar.subviews.first?.subviews.compactMap({ $0 as? UITextField }) {
        textFields.forEach { $0.tintColor = UIColor.darkGray }
}
Dris
  • 881
  • 8
  • 19
Frederic Adda
  • 5,905
  • 4
  • 56
  • 71