web-dev-qa-db-fra.com

Impossible de changer la couleur d'arrière-plan de la barre de recherche

J'ai une barre de recherche:

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 la partie saisie de texte. 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 changer la couleur de fond de ma partie textInput UISearchBar et ce que j'ai fait de travers?

14
Orkhan Alizade

Si vous voulez seulement le changer dans votre ViewController et que vous ne voulez nulle part ailleurs, alors 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 cela change dans toute l'application et que vous ciblez iOS 9.0 ou une version ultérieure, vous devriez utiliser 

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

Vous ajoutez le code ci-dessous dans ViewDidLoad et modifiez la couleur d’arrière-plan du champ de texte ROUGE,

for subView in searchBar.subviews
{
    for subView1 in subView.subviews
    {

        if subView1.isKindOfClass(UITextField)
        {
            subView1.backgroundColor = UIColor.redColor()
        }
    }

}

Couleur rouge de TextField dans SearchBar.

 enter image description here

9
Kirit Modi

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

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

Pour cela, utilisez uniquement les API Apple: créez une image et utilisez setSearchFieldBackgroundImage:

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

Il animera même les coins correctement si vous créez un rectangle arrondi et des boutons d'affichage et de masquage dynamiques. 

Exemple utilisant cette image:  enter image description here

 enter image description here

5
SuperDuperTango

Je le fais avec cette méthode (solution Swift 3+):

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

Comme @aliamcami, toutes les réponses précédentes ne fonctionnaient pas comme prévu, soit la réponse ne fonctionnait pas pour moi, soit elle fonctionnait, mais elle nécessitait trop de code "factice". Je partage donc une autre réponse écrite dans Swift 4 avec une logique simplifiée:

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 est la sous-vue "_UISearchBarSearchFieldBackgroundView" qui ajoute des effets visuels derrière la UIFieldEditor.


Édité

Après quelques développements et de nombreux bugs, j'ai fini avec cette solution elegant (que Apple ne serait sûrement pas ravie d'approuver, mais que je ne connais pas) et qui fonctionne de iOS 10 à 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...
}

Lorsque la searchBar est dans la tableHeaderView, le code ci-dessus peut être appelé dans viewWillAppear, mais s'il l'est dans la navigationItem sur iOS 11 et versions ultérieures, il doit être appelé dans viewDidAppear.

4
Ángel Téllez

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

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 avec XCode 7 et iOS 9, et j’ai remarqué que sur le Web, beaucoup d’autres ont indiqué que cela ne fonctionnait pas non plus pour eux. J'ai découvert que la sous-vue UITextField n'est pas créée (ou du moins, elle n'est pas ajoutée en tant que sous-vue) tant qu'elle n'est pas référencée. Le champ réservé à cet effet peut être référencé. Vous pouvez par exemple ajouter cette ligne avant la recherche les sous-vues de la classe UITextField:

searchBar.placeholder = searchBar.placeholder
2
Ted

Définissez n'importe quelle couleur 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!
  }
}
1
ale_stro

Voici la solution

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

Essayez juste votre code comme ci-dessous dans la cour de récréation. 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()
        }
    }
}
0
Anni S

Je viens juste de partager le SEUL moyen de changer la couleur d’arrière-plan de la barre de recherche textField parce que je ne l’ai pas encore vue, et aucune des autres suggestions, ici ou dans d’autres sites, ne fonctionne pour moi. 

  • Obtenez le textField dans la barre de recherche, comme la réponse de @Steve ... tout fonctionne ici tant que vous obtenez le textField. Ce n’était pas mon problème, le problème, c’est qu’il ne mesurait pas les couleurs que j’avais fixées ici, cela ne fonctionnait pas extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } }

  • Créez un nouveau calque avec la taille de la barre de navigation let layer = CALayer() layer.backgroundColor = UIColor.white.withAlphaComponent(0.5).cgColor //Set your color here layer.frame = navigationBar.frame

  • Définissez le nouveau calque comme sous-couche pour le champ de texte 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)
  • voilà, vous aurez un arrière-plan textField arrondi avec la couleur de votre choix. 
0
aliamcami

Voici la 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;
        }
    }
}

Mais s'il vous plaît noter que cela ne fonctionne que dans iOS 11.0 et versions ultérieures. Alors n'oubliez pas d'ajouter avant 

if #available(iOS 11.0, *) {}
0
H.Jacob