How can I change the UISearchBar search text color?
IosSwiftUisearchbarIos Problem Overview
How can I change the text color of a UISearchBar
?
Ios Solutions
Solution 1 - Ios
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
Solution 2 - Ios
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.
Solution 3 - Ios
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
Solution 4 - Ios
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]
Solution 5 - Ios
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
}
}
Solution 6 - Ios
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.
Solution 7 - Ios
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
Solution 8 - Ios
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")
}
}
Solution 9 - Ios
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.
Solution 10 - Ios
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 !).
Solution 11 - Ios
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
}
}
Solution 12 - Ios
Swift 5.2 & iOS 13.3.1:-
It works fine.
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
Solution 13 - Ios
(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 }
}
}
Solution 14 - Ios
This worked for me.
if #available(iOS 13.0, *) {
searchBar.searchTextField.textColor = .white
}
Solution 15 - Ios
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;
}
}
}
Solution 16 - Ios
//Try this guy
yourSearchbar.searchTextField.textColor = .white
Solution 17 - Ios
In my situation solution is
id appearance = [UITextField appearanceWhenContainedInInstancesOfClasses:@[UISearchBar.class, BCRSidebarController.class]];
[appearance setTextColor:[UIColor.whiteColor colorWithAlphaComponent:0.56]];
Solution 18 - Ios
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
Solution 19 - Ios
Swift 5:
searchBar[keyPath: \.searchTextField].textColor = UIColor(...)
Solution 20 - Ios
In Swift 5 you can do something like below:
yourSearchBar.searchTextField.textColor = .yourColor
Solution 21 - Ios
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];
}
Solution 22 - Ios
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{
}
}
Solution 23 - Ios
Swift 5 Xcode 11.4 iOS 13.4
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = .white
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = .systemFont(ofSize: 13)