Unable to change the background color of the search bar

I have a search bar:

let searchBar:UISearchBar = UISearchBar(frame: CGRectMake((searchView.frame.width - UIScreen.mainScreen().bounds.width / 1.6) / 2, 0, UIScreen.mainScreen().bounds.width / 1.6, 24)) 

and I want to change the background color for text input. For this I tried:

 searchBar.barTintColor = UIColor(red: 0/255, green: 74/255, blue: 103/255, alpha: 1) searchBar.backgroundColor = UIColor.redColor() 

but both of these options do not work. How do I change the background color of my UISearchBar I / O part and what did I do wrong?

+18
ios swift uisearchbar
source share
18 answers

If you want to change it in your ViewController and don’t want it to fail anywhere else, use

 for view in searchBar.subviews { for subview in view.subviews { if subview .isKindOfClass(UITextField) { let textField: UITextField = subview as! UITextField textField.backgroundColor = UIColor.redColor() } } } 

But if you want this to be a change of the whole application and targeting on iOS 9.0 or later, then there should be use outerWhenContainedInInstancesOfClasses, for example

 UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.redColor() 
+14
source share

You add the code below to ViewDidLoad and change the background color of the RED field field,

 for subView in searchBar.subviews { for subView1 in subView.subviews { if subView1.isKindOfClass(UITextField) { subView1.backgroundColor = UIColor.redColor() } } } 

The red color of the TextField in the SearchBar.

enter image description here

+10
source share

For Swift 3+ use this:

 for subView in searchController.searchBar.subviews { for subViewOne in subView.subviews { if let textField = subViewOne as? UITextField { subViewOne.backgroundColor = UIColor.red //use the code below if you want to change the color of placeholder let textFieldInsideUISearchBarLabel = textField.value(forKey: "placeholderLabel") as? UILabel textFieldInsideUISearchBarLabel?.textColor = UIColor.blue } } } 
+10
source share

The only way to do this with the Apple API is to create an image and use setSearchFieldBackgroundImage :

 self.searchBar.setSearchFieldBackgroundImage(UIImage(named: "SearchFieldBackground"), for: UIControlState.normal) 

It will even animate corners correctly if you create a rounded rectangle and dynamically display and hide the buttons.

An example of using this image: enter image description here

enter image description here

+8
source share

Like @aliamcami, all of the previous answers did not work as I expected, either the answer did not work for me, or it works, but it takes too much “dummy” code. Therefore, I am sharing another answer written in Swift 4 with simplified logic:

 for textField in searchController.searchBar.subviews.first!.subviews where textField is UITextField { textField.subviews.first?.backgroundColor = .white textField.subviews.first?.layer.cornerRadius = 10.5 //I set 10.5 because is approximately the system value textField.subviews.first?.layer.masksToBounds = true //Continue changing more properties... } 

textField.subviews.first is a subview of "_UISearchBarSearchFieldBackgroundView" that adds visual effects behind the UIFieldEditor .


edited

After some development and a lot of mistakes, I ended up with this elegant solution (which I'm sure Apple will not be happy to approve, but I don’t know) that works with iOS 10 on iOS 12 :

 if let textField = searchBar.value(forKey: "searchField") as? UITextField { textField.backgroundColor = myColor //textField.font = myFont //textField.textColor = myTextColor //textField.tintColor = myTintColor // And so on... let backgroundView = textField.subviews.first if #available(iOS 11.0, *) { // If 'searchController' is in 'navigationItem' backgroundView?.backgroundColor = UIColor.white.withAlphaComponent(0.3) //Or any transparent color that matches with the 'navigationBar color' backgroundView?.subviews.forEach({ $0.removeFromSuperview() }) // Fixes an UI bug when searchBar appears or hides when scrolling } backgroundView?.layer.cornerRadius = 10.5 backgroundView?.layer.masksToBounds = true //Continue changing more properties... } 

When the searchBar is in tableHeaderView above code can be called in viewWillAppear , but if it is in navigationItem viewWillAppear on iOS 11 and above, it must be called in viewDidAppear .

+8
source share

Just like this one

 let searchBar:UISearchBar = UISearchBar(frame: CGRectMake((searchView.frame.width - UIScreen.mainScreen().bounds.width / 1.6) / 2, 0, UIScreen.mainScreen().bounds.width / 1.6, 24)) let searchTextField = searchBar.valueForKey("_searchField") as? UITextField searchTextField?.backgroundColor = UIColor.redColor() 
+7
source share

I do this with this method (Swift 3+):

 let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField textFieldInsideSearchBar?.backgroundColor = UIColor.red 
+5
source share

FWIW I solve this problem by creating a computed variable called textField.

 extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } } 
+3
source share

A very general answer to this question on the Internet is the solution described above:

 for subView in searchBar.subviews { for subViewInSubView in subView.subviews { if subViewInSubView.isKindOfClass(UITextField) { subViewInSubView.backgroundColor = UIColor.purpleColor() } } } 

But this did not work for me using Xcode 7 and iOS 9, and I noticed that many others around the world reported that they also did not work for them. I found that the UITextField view was not created (or at least it was not added as a view) until it was specified, and one of the ways it could refer to was a placeholder field, for example, you could would add this line before searching for subviews for the UITextField class:

 searchBar.placeholder = searchBar.placeholder 
+2
source share

Here's the solution:

 func customizeSearchBar(){ if let textfield = searchController.searchbar.value(forKey: "searchField") as? UITextField { textfield.textColor = UIColor.blue if let backgroundview = textfield.subviews.first { // Background color backgroundview.backgroundColor = UIColor.white // Rounded corner backgroundview.layer.cornerRadius = 10; backgroundview.clipsToBounds = true; } } } 

But keep in mind that this only works on iOS 11.0 and later. Therefore, do not forget to add before

 if #available(iOS 11.0, *) {} 
+2
source share

I experimented with the searchBar and searchTextField properties when I found the solution above.

Below I have listed the steps to achieve the desired result:

  1. Set searchTextField border style to .none
  2. Set the background color of searchTextField to the color you want
  3. Change the angular radius of the searchTextField layer to 10
  4. Set searchTextField clipToBounds property to true

Next, I have provided the code below for your reference:

  let searchController = UISearchController(searchResultsController: nil) navigationItem.searchController = searchController searchController.searchBar.barTintColor = viewBackgroundColor searchController.searchBar.backgroundColor = viewBackgroundColor searchController.searchBar.searchTextField.borderStyle = .none searchController.searchBar.searchTextField.backgroundColor = .white searchController.searchBar.searchTextField.layer.cornerRadius = 10 searchController.searchBar.searchTextField.clipsToBounds = true 

Note: searchTextField is in beta and is available on iOS 13

+2
source share

Set any color you want. SWIFT 3

 public extension UISearchBar { public func setStyleColor(_ color: UIColor) { tintColor = color guard let tf = (value(forKey: "searchField") as? UITextField) else { return } tf.textColor = color if let glassIconView = tf.leftView as? UIImageView, let img = glassIconView.image { let newImg = img.blendedByColor(color) glassIconView.image = newImg } if let clearButton = tf.value(forKey: "clearButton") as? UIButton { clearButton.setImage(clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate), for: .normal) clearButton.tintColor = color } } } extension UIImage { public func blendedByColor(_ color: UIColor) -> UIImage { let scale = UIScreen.main.scale if scale > 1 { UIGraphicsBeginImageContextWithOptions(size, false, scale) } else { UIGraphicsBeginImageContext(size) } color.setFill() let bounds = CGRect(x: 0, y: 0, width: size.width, height: size.height) UIRectFill(bounds) draw(in: bounds, blendMode: .destinationIn, alpha: 1) let blendedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return blendedImage! } } 
+1
source share

UISearchBar Extension Using Swift 4 Based on Most Voted Response

 extension UISearchBar { func tfBackgroundColor(color: UIColor){ for view in self.subviews { for subview in view.subviews { if subview is UITextField { let textField: UITextField = subview as! UITextField textField.backgroundColor = color } } } } } 
+1
source share

I made one extension to the UISearchBar & category to customize the text in the search bar.

Compatible with iOS 9 to iOS 13.

Swift 4+

 import UIKit extension UISearchBar { var dtXcode: Int { if let dtXcodeString = Bundle.main.infoDictionary?["DTXcode"] as? String { if let dtXcodeInteger = Int(dtXcodeString) { return dtXcodeInteger } } return Int() } // Due to searchTextField property who available iOS 13 only, extend this property for iOS 13 previous version compatibility var compatibleSearchTextField: UITextField { guard #available(iOS 13.0, *), dtXcode >= 1100 else { return legacySearchField } return self.searchTextField } var legacySearchField: UITextField { guard let textField = self.subviews.first?.subviews.last as? UITextField else { return UITextField() } return textField } } 

Usage example:

 var searchController: UISearchController? searchController?.searchBar.compatibleSearchTextField.textColor = UIColor.XXX searchController?.searchBar.compatibleSearchTextField.backgroundColor = UIColor.XXX 

Objective-c

UISearchBar + SearchTextField.h

 #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface UISearchBar (SearchTextField) // Due to searchTextField property who available iOS 13 only, extend this property for iOS 13 previous version compatibility @property (nonatomic, readonly) UITextField *compatibleSearchTextField; @end NS_ASSUME_NONNULL_END 

UISearchBar + SearchTextField.m

 #import "UISearchBar+SearchTextField.h" @implementation UISearchBar (SearchTextField) - (UITextField *)compatibleSearchTextField { if (@available(iOS 13.0, *)) { #ifdef __IPHONE_13_0 return self.searchTextField; #else return (UITextField *)[self valueForKey:@"searchField"]; #endif } else { return [[[self.subviews firstObject] subviews] lastObject]; } } @end 

Usage example:

 - (UISearchBar *)searchBar { if (!_searchBar) { _searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(X, X, X, X)]; _searchBar.compatibleSearchTextField.textColor = [UIColor XXX]; _searchBar.compatibleSearchTextField.backgroundColor = [UIColor XXX]; } return _searchBar } 

For more details, please contact Gist

+1
source share

Just try your code as shown below on the playground. If this still doesn't work, add another code to your question ...

 let searchView = UIView(frame: CGRect(x: 0.0,y: 0.0, width: 100, height: 50)) let searchBar:UISearchBar = UISearchBar(frame: CGRectMake((searchView.frame.width - UIScreen.mainScreen().bounds.width / 1.6) / 2, 0, UIScreen.mainScreen().bounds.width / 1.6, 24)) for subView in searchBar.subviews { for subViewInSubView in subView.subviews { if subViewInSubView.isKindOfClass(UITextField) { subViewInSubView.backgroundColor = UIColor.purpleColor() } } } 
0
source share

I just came to share ONLY the way to change the background color for the searchbar text field, because I have not seen it in any answer yet, and none of the other offers here or on other sites worked for me.

  • Get textField from the search bar, just like the answer from @Steve ... everything works here as long as you get textField. This is not my problem, the fact is that it did not change the colors that I set here, it did not work extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } } extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } } extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } } extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } } extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } }

  • Create a new layer with the size let layer = CALayer() layer.backgroundColor = UIColor.white.withAlphaComponent(0.5).cgColor//Set your color here layer.frame = navigationBar.frame navigationBar let layer = CALayer() layer.backgroundColor = UIColor.white.withAlphaComponent(0.5).cgColor//Set your color here layer.frame = navigationBar.frame

  • Set a new layer as a sublevel for navigationBar.textField?.layer.masksToBounds = true//to make sure you get the rounded corners navigationBar.textField?.layer.cornerRadius = 14//Round it as you wish navigationBar.textField?.layer.addSublayer(layer) by text navigationBar.textField?.layer.masksToBounds = true//to make sure you get the rounded corners navigationBar.textField?.layer.cornerRadius = 14//Round it as you wish navigationBar.textField?.layer.addSublayer(layer)
  • that is, you will have a rounded textField background with whatever color you want.
0
source share

the solution provided by @ Ángel Téllez also helped me! Thanks Angel! I’m not sure that it will work for iOS 10, but it works for 11. In addition, if there is one minor malfunction of the user interface, where for the flash (under the second), there is a white line that appears between the navigation header and the search bar controller. I don’t know why this is happening, but I'm glad it works!

0
source share

Here is the solution

 func configureSearchBar() { for textField in searchBar.subviews.first!.subviews where textField is UITextField { textField.backgroundColor = .cyan } } 
0
source share

All Articles