How can I change the text color of a UISearchBar
?
25 Answers
You have to access the UITextField
inside the UISearchBar. You can do that by using valueForKey("searchField")
var textFieldInsideSearchBar = yourSearchbar.valueForKey("searchField") as? UITextField
textFieldInsideSearchBar?.textColor = yourcolor
Swift 3 update
let textFieldInsideSearchBar = yourSearchbar.value(forKey: "searchField") as? UITextField
textFieldInsideSearchBar?.textColor = yourcolor
-
Thanks! But is that API public or private? – MrTourkos Feb 15 '15 at 17:43
-
It doesn't compile. After a few changes it did, but then threw a runtime error complaining "Array index out of range" and if i change it to subView[0] it's a UIView that cannot be casted to a textField. Notice that i'm using Swift 1.2 if that has something to do. Thanks and sorry for the late reply. – MrTourkos Feb 20 '15 at 12:16
-
1I've edited my answer. You can access the field by using valueforkey("searchField") – Christian Feb 20 '15 at 12:20
-
Alright now working great! Just a minor, you need to unwrap textFieldInsideSearchBar?.textColor = yourcolor to access textColor Thanks man! – MrTourkos Feb 20 '15 at 12:24
-
How did you find the name of the searchField value ? I'd like to change the font of the cancel button but I don't find the value for it. – YoanGJ Jun 01 '16 at 08:37
-
not working at all ---- Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[
valueForUndefinedKey:]: this class is not key value coding-compliant for the key searchField.' – bLacK hoLE Jun 04 '16 at 09:06 -
7It's not private API but it's very fragile and can break on any iOS update. You shouldn't ever use things like these in production code – Lope Jul 10 '17 at 10:19
-
@NextDeveloper Have you checked how long ago this answer was posted? It’s possible that it doesn’t work anymore. Feel free to show another approach. – Christian Aug 25 '17 at 09:40
-
3@Christian - it doesn't matter when the original answer was posted, it still relies on private API. If it was public, you wouldn't need to access `searchField` via KVC. – Greg Brown Nov 29 '17 at 12:05
-
2Downvote. See @juanjo's answer and my comment for a much more robust approach approved by Apple and far less likely to break. – RobP Jun 27 '18 at 02:19
-
2Don't use this answer, you are accessing private APIs and it could get your app rejected. – aryaxt Sep 23 '18 at 17:50
If you want to set text color for UISearchBar in storyboard (without code), it is easy to do as well (in identity inspector). Here is a red text for search bar.

- 2,030
- 17
- 14
If you only need to make it readable on a dark background you can change the barStyle. The following makes text and buttons in the searchbar white:
searchController.searchBar.barStyle = .black

- 792
- 5
- 8
Working in Swift 4 for me:
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.white]
Swift 4.2, IOS 12:
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
public extension UISearchBar {
public func setTextColor(color: UIColor) {
let svs = subviews.flatMap { $0.subviews }
guard let tf = (svs.filter { $0 is UITextField }).first as? UITextField else { return }
tf.textColor = color
}
}

- 19,175
- 22
- 126
- 148
-
-
You can also add "searchField.backgroundColor" to control the background color of the text field separate from the bar tint. – Sherwin Zadeh Nov 10 '19 at 21:40
This works for me on iOS 11, Xcode 9:
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.blue
I write it in the AppDelegate
but I guess it works if you put it somewhere else too.

- 3,737
- 3
- 39
- 44
-
3This is a much more robust approach than the key-value nonsense in the accepted answer and other answers. However, Apple in their wisdom has deprecated the API you use here and offers a new version for iOS 9.0 and above, like so: `[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor blueColor]];` This is of course Objective-C, with obvious translation to Swift using `appearance(whenContainedInInstancesOf:)` – RobP Jun 27 '18 at 02:16
-
2
-
@RobP this is the same hack based on assumption that there is a `UITextField` inside the `UISearchBar`. But instead of localizing ugliness in a place of usage it's spilling it all over the project. – Zapko May 18 '21 at 16:42
The most convenient way I think is to set a textColor
property in UISearchBar
.
Swift 3.0
extension UISearchBar {
var textColor:UIColor? {
get {
if let textField = self.value(forKey: "searchField") as?
UITextField {
return textField.textColor
} else {
return nil
}
}
set (newValue) {
if let textField = self.value(forKey: "searchField") as?
UITextField {
textField.textColor = newValue
}
}
}
}
Usage
searchBar.textColor = UIColor.blue // Your color
Swift 2.3
extension UISearchBar {
var textColor:UIColor? {
get {
if let textField = self.valueForKey("searchField") as? UITextField {
return textField.textColor
} else {
return nil
}
}
set (newValue) {
if let textField = self.valueForKey("searchField") as? UITextField {
textField.textColor = newValue
}
}
}
}
You would use it as:
searchBar.textColor = UIColor.blueColor() // Your color

- 6,308
- 3
- 50
- 73
-
-
1
-
Yeah, I wanted to change the placholder text color. Now I found the solutions. Thanks anyway – Kingalione Mar 08 '17 at 12:47
Since Xcode 11 and iOS 13 it has become possible to access the text field directly:
searchBar.searchTextField
You could write some code to always make it accessible like this.
extension UISearchBar {
public var textField: UITextField? {
if #available(iOS 13.0, *) {
return searchTextField
}
guard let firstSubview = subviews.first else {
assertionFailure("Could not find text field")
return nil
}
for view in firstSubview.subviews {
if let textView = view as? UITextField {
return textView
}
}
assertionFailure("Could not find text field")
return nil
}
}
You could also make it not optional with fatal errors, this code is tested since iOS 7 up to iOS 13GM. But i would just go for the optional version.
extension UISearchBar {
public var textField: UITextField {
if #available(iOS 13.0, *) {
return searchTextField
}
guard let firstSubview = subviews.first else {
fatalError("Could not find text field")
}
for view in firstSubview.subviews {
if let textView = view as? UITextField {
return textView
}
}
fatalError("Could not find text field")
}
}

- 3,450
- 4
- 32
- 45
Try this,
searchBar.searchTextField.textColor = .white
I am using this with app targeted iOS 11 onwards.
[Update] I observed, the app crashes on older versions (< iOS 13), But compiler never complained about the version check, someone please explain why this happened.

- 2,135
- 1
- 25
- 29
I tried a few of the solutions written above but they didn't work (anymore, I guess).
If you only want to handle iOS 13:
mySearchBar.searchTextField.textColor = .red
But if you want to handle older iOS too, Here is the way I did :
Create a custom UISearchBar
class, called SearchBar : UISearchBar, UISearchBarDelegate
This SearchBar
will have the UISearchBarDelegate
methods I wanna handle and its delegate
set.
And I add to the class:
var textField: UITextField? {
if #available(iOS 13.0, *) {
return self.searchTextField
}
return subviews.first?.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField
}
Short explanation:
With iOS13 now, you can access the UITextField
thanks to UISearchBar.searchTextField
, which is of type UISearchTextField
, which inherits from UITextField
.
Since I know my hierarchy, I know my textField
won't be nill
for older versions so in both case, I get a textfield I can easily customize, working on every version, from 9 to 13 today.
Here is the full code needed to make it work:
class SearchBar: UISearchBar, UISearchBarDelegate {
var textField: UITextField? {
if #available(iOS 13.0, *) {
return self.searchTextField
}
return subviews.first?.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField
}
override func awakeFromNib() {
super.awakeFromNib()
delegate = self
if let textField = textField {
textField.textColor = .red
textField.clearButtonMode = .whileEditing
textField.returnKeyType = .search
}
}
}
You can also set some customization on SearchBar
by adding this on the :
let searchBar = UISearchBar.appearance(whenContainedInInstancesOf: [SearchBar.self])
searchBar.backgroundImage = UIImage()
searchBar.isTranslucent = false
searchBar.returnKeyType = .search
Then you set it to the XIB / Storyboard and you handle it like if it were a simple UISearchBar
(if you did not forget the delegates !).

- 306
- 3
- 17
You can do this by accessing the UITextField inside the searchBar, then you can change its background color, text color, and all other UITextField properties
add the following extension to access the textField
extension UISearchBar {
/// Return text field inside a search bar
var textField: UITextField? {
let subViews = subviews.flatMap { $0.subviews }
guard let textField = (subViews.filter { $0 is UITextField }).first as? UITextField else { return nil
}
return textField
}
}

- 1,332
- 13
- 17
Swift 5.2 & iOS 13.3.1:-
It works fine.
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]

- 97
- 3
This worked for me.
if #available(iOS 13.0, *) {
searchBar.searchTextField.textColor = .white
}

- 155
- 9
(This solution only tested for Xcode 10 & iOS 12.) Add an extension to access the search bar's text field:
extension UISearchBar {
var textField: UITextField? {
return subviews.first?.subviews.compactMap { $0 as? UITextField }.first
}
}
Then use that property to set the text color of the text field in your search bar:
let searchBar = UISearchBar()
searchBar.textField?.textColor = UIColor.white // or whichever color you want
// EDIT
The code above does not work for iOS 13. A better way to handle this is to use:
extension UISearchBar {
var textField: UITextField? {
return self.subviews(ofType: UITextField.self).first
}
}
extension UIView {
var recursiveSubviews: [UIView] {
return self.subviews + self.subviews.flatMap { $0.recursiveSubviews }
}
func subviews<T: UIView>(ofType: T.Type) -> [T] {
return self.recursiveSubviews.compactMap { $0 as? T }
}
}

- 984
- 7
- 13
-
for iOS 13 **return subviews.first?.subviews.last?.subviews.compactMap { $0 as? UITextField }.last** – Taras Nov 05 '19 at 04:04
In Swift 5 you can do something like below:
yourSearchBar.searchTextField.textColor = .yourColor

- 2,894
- 4
- 33
- 48

- 709
- 11
- 29
Here is a Xamarin.iOS C# version of the "find the UITextField" approach. It will not crash if the UITextField disappears in future iOS view hierarchy.
var tf = searchBar.AllSubViews().FirstOrDefault(v => v is UITextField);
if (tf != null)
(tf as UITextField).TextColor = UIColor.White;
public static IEnumerable<UIView> AllSubViews(this UIView view)
{
foreach (var v in view.Subviews)
{
yield return v;
foreach (var sv in v.AllSubViews())
{
yield return sv;
}
}
}

- 1,546
- 2
- 19
- 31
In my situation solution is
id appearance = [UITextField appearanceWhenContainedInInstancesOfClasses:@[UISearchBar.class, BCRSidebarController.class]];
[appearance setTextColor:[UIColor.whiteColor colorWithAlphaComponent:0.56]];

- 299
- 4
- 10
Obj-C
UITextField *textField = [self.yourSearchbar valueForKey:@"_searchField"];
textField.textColor = [UIColor redColor];
Swift 4.x
let textField = yourSearchbar.value(forKey: "searchField") as? UITextField
textField?.textColor = UIColor.red

- 2,241
- 1
- 22
- 27
you can set the color for self.searchBar.searchTextField.textColor below code in viewDidLoad works.
- (void)viewDidLoad {
[super viewDidLoad];
self.searchBar.searchTextField.textColor = [UIColor whiteColor];
}

- 1
- 1
SwiftUI, Swift 5
In SwiftUI, the
init(){
UITextfiled.appearance().textColor = .white
}
doesn't work. But you can just use the
.foregroundColor(.white)
modifier to change the searchable()'s text color.
If you also want to change the tintColor of the searchbar inside a NavigationView{}. You could init the inti() function of the view.
init(){
UINavigationBar.appearance().tintColor = .white
}
var body:some View{
NavigationView{
}
}

- 479
- 7
- 14
In my case I had the searchBar of a UISearchController in the navigationBar. For some reason textColor only works when called after adding the searchController as an item in the navigation.
previous code...
navigationItem.searchController = searchController
// Only after the assignment it works
searchController.searchBar.searchTextField.textColor = your color

- 31
- 4
set searchTextField.textColor property of the UISearchBar to change the text color:
let searchBar = UISearchBar()
searchBar.searchTextField.textColor = .white
Or, for storyboard:
@IBOutlet weak var searchBar: UISearchBar!
searchBar.searchTextField.textColor = .white

- 17
- 3
Swift 5 Xcode 11.4 iOS 13.4
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = .white
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = .systemFont(ofSize: 13)

- 616
- 7
- 12