Impossible de modifier la couleur d'arrière-plan de la barre de search

J'ai une barre de search:

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

et je veux changer la couleur de fond de partie d'input de text. Pour cela, j'ai essayé:

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

mais ces deux variantes ne fonctionnent pas. Comment puis-je changer la couleur de fond de ma partie UISearchBar textInput et ce que j'ai fait de mal?

Voir le projet Démo : Démo

Vous ajoutez le code ci-dessous dans ViewDidLoad et modifiez la couleur d'arrière-plan du champ de text RED,

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

Couleur rouge de TextField dans SearchBar.

entrez la description de l'image ici

Si vous voulez seulement le changer dans votre ViewController et que vous ne voulez pas d'autre application, utilisez

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

Mais si vous voulez que ce soit le changement dans toute l'application et ciblant l'iOS 9.0 ou plus tard, alors vous devriez utiliser appearanceWhenContainedInInstancesOfClasses comme

 UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.redColor() 

Pour Swift 3+, utilisez ceci:

 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 } } } 

Juste comme ça

 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() 

Une réponse très commune à cette question sur le web est cette solution décrite ci-dessus:

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

Mais cela n'a pas fonctionné pour moi en utilisant XCode 7 et iOS 9, et j'ai remarqué que sur le web beaucoup d'autres ont rapporté que cela ne fonctionnait pas pour eux non plus. J'ai découvert que la sous-vue UITextField n'est pas créée (ou du less elle n'est pas ajoutée en tant que sous-vue) jusqu'à ce qu'elle soit référencée, et que le champ de l'espace réservé puisse être référencé, par exemple, on pourrait append cette ligne avant de chercher les sous-vues de la class UITextField:

 searchBar.placeholder = searchBar.placeholder 

La façon de faire cela en utilisant seulement les API Apple est de créer une image et d'utiliser setSearchFieldBackgroundImage :

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

Il va même animer les coins correctement si vous créez un rectangle arrondi et afficher et masquer dynamicment les buttons.

Exemple utilisant cette image: entrez la description de l'image ici

entrez la description de l'image ici

Définissez n'importe quelle couleur que vous voulez. 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! } } 

FWIW Je résous ce problème en créant une variable calculée nommée textField.

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

Juste essayez votre code comme ci-dessous dans le terrain de jeu. Si cela ne fonctionne toujours pas, ajoutez plus de code à votre 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() } } } 

Je le fais de cette façon (solution Swift 3+):

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