Comment puis-je changer la couleur du texte de recherche UISearchBar?

88

Comment puis-je changer la couleur du texte d'un UISearchBar?

MrTourkos
la source

Réponses:

108

Vous devez accéder à l' UITextFieldintérieur de UISearchBar. Vous pouvez le faire en utilisantvalueForKey("searchField")

var textFieldInsideSearchBar = yourSearchbar.valueForKey("searchField") as? UITextField

textFieldInsideSearchBar?.textColor = yourcolor

Mise à jour Swift 3

let textFieldInsideSearchBar = yourSearchbar.value(forKey: "searchField") as? UITextField

textFieldInsideSearchBar?.textColor = yourcolor
Christian
la source
1
J'ai modifié ma réponse. Vous pouvez accéder au champ en utilisant valueforkey ("searchField")
Christian
7
Ce n'est pas une API privée mais elle est très fragile et peut se briser sur n'importe quelle mise à jour iOS. Vous ne devriez jamais utiliser des choses comme celles-ci dans le code de production
Lope
2
@Christian - peu importe quand la réponse originale a été publiée, elle repose toujours sur une API privée. S'il était public, vous n'auriez pas besoin d'accéder searchFieldvia KVC.
Greg Brown
1
Voter contre. Voir la réponse de @ juanjo et mon commentaire pour une approche beaucoup plus robuste approuvée par Apple et beaucoup moins susceptible de casser.
RobP
1
N'utilisez pas cette réponse, vous accédez à des API privées et votre application pourrait être rejetée.
aryaxt
64

Si vous souhaitez définir la couleur du texte pour UISearchBar dans le storyboard (sans code), il est également facile de le faire (dans l'inspecteur d'identité). Voici un texte rouge pour la barre de recherche.

entrez la description de l'image ici

interrompre
la source
2
Il est préférable d'avoir moins de code pour les éléments de vue. Merci.
NRR
Solution parfaite!
lun
49

Travailler dans Swift 4 pour moi:

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]
chronikum
la source
Travailler pour moi.
Surjeet Rajput
et il change de couleur pour chaque barre de recherche dans le module?
Zaporozhchenko Oleksandr
48

Si vous avez seulement besoin de le rendre lisible sur un fond sombre, vous pouvez changer le barStyle. Ce qui suit rend le texte et les boutons de la barre de recherche blancs:

searchController.searchBar.barStyle = .black
Bacon
la source
@Bacon, ça a aidé aussi! Merci
Goppinath
32
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
    }
}
Adam Waite
la source
Comme votre solution. Merci.
Bagusflyer
Vous pouvez également ajouter "searchField.backgroundColor" pour contrôler la couleur d'arrière-plan du champ de texte distinct de la teinte de la barre.
Sherwin Zadeh
13

Cela fonctionne pour moi sur iOS 11, Xcode 9:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.blue

Je l'écris dans le AppDelegatemais je suppose que cela fonctionne si vous le mettez ailleurs aussi.

Juanjo
la source
3
Il s'agit d'une approche beaucoup plus robuste que le non-sens clé-valeur dans la réponse acceptée et d'autres réponses. Cependant, Apple dans sa sagesse a désapprouvé l'API que vous utilisez ici et propose une nouvelle version pour iOS 9.0 et au-dessus, comme ceci: [[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor blueColor]];Il s'agit bien sûr d'Objective-C, avec une traduction évidente en Swift en utilisantappearance(whenContainedInInstancesOf:)
RobP
2
Cela ne semble pas fonctionner pour moi dans Xcode 10, iOS 12, sur un appareil réel.
Oded
10

Le moyen le plus pratique à mon avis est de définir une textColorpropriété 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
         }
     }
 }
} 

Vous l'utiliseriez comme:

searchBar.textColor = UIColor.blueColor() // Your color
Tal Zion
la source
ne fonctionne pas pour moi. quand définissez-vous la propriété textcolor?
Kingalione
1
@Kingalione, vous pouvez définir cela dans 'viewDidLoad ()'
Tal Zion
Ouais, je voulais changer la couleur du texte du placholder. Maintenant, j'ai trouvé les solutions. Merci quand même
Kingalione
10

Depuis Xcode 11 et iOS 13, il est devenu possible d'accéder directement au champ de texte:

searchBar.searchTextField

Vous pouvez écrire du code pour toujours le rendre accessible comme ça.

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

Vous pouvez également le rendre non facultatif avec des erreurs fatales, ce code est testé depuis iOS 7 jusqu'à iOS 13GM. Mais j'opterais pour la version optionnelle.

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")
    }
}
Saren Inden
la source
Finalement! Nous pouvons accéder directement au champ de texte. Merci, Saren.
Mark Moeykens
4

Essaye ça,

searchBar.searchTextField.textColor = .white

J'utilise ceci avec l'application ciblée sur iOS 11 et les versions ultérieures.

[Mise à jour] J'ai observé, l'application plante sur les anciennes versions (<iOS 13), mais le compilateur ne s'est jamais plaint de la vérification de la version, quelqu'un s'il vous plaît expliquer pourquoi cela s'est produit.

boucle infinie
la source
3

Vous pouvez le faire en accédant à UITextField dans la barre de recherche, puis vous pouvez modifier sa couleur d'arrière-plan, la couleur du texte et toutes les autres propriétés UITextField

ajoutez l'extension suivante pour accéder au 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
    }
}
Omar Albeik
la source
3

J'ai essayé quelques-unes des solutions écrites ci-dessus mais elles n'ont pas fonctionné (plus, je suppose).

Si vous souhaitez uniquement gérer iOS 13:

mySearchBar.searchTextField.textColor = .red

Mais si vous souhaitez également gérer un iOS plus ancien, voici ce que j'ai fait:

Créez une UISearchBarclasse personnalisée , appelée SearchBar : UISearchBar, UISearchBarDelegate This SearchBaraura les UISearchBarDelegateméthodes que je veux gérer et son delegateensemble.

Et j'ajoute à la classe:

    var textField: UITextField? {
        if #available(iOS 13.0, *) {
            return self.searchTextField
        }
        return subviews.first?.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField
    }

Brève explication:

Avec iOS13 maintenant, vous pouvez accéder au UITextFieldmerci de UISearchBar.searchTextField, qui est de type UISearchTextField, qui hérite de UITextField.

Puisque je connais ma hiérarchie, je sais que je textFieldne serai pas nillpour les anciennes versions, donc dans les deux cas, j'obtiens un champ de texte que je peux facilement personnaliser, en travaillant sur toutes les versions, de 9 à 13 aujourd'hui.

Voici le code complet nécessaire pour le faire fonctionner:


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

}

Vous pouvez également définir une certaine personnalisation SearchBaren ajoutant ceci sur le:

        let searchBar = UISearchBar.appearance(whenContainedInInstancesOf: [SearchBar.self])
        searchBar.backgroundImage = UIImage()
        searchBar.isTranslucent = false
        searchBar.returnKeyType = .search

Ensuite, vous le définissez sur le XIB / Storyboard et vous le gérez comme s'il s'agissait d'un simple UISearchBar(si vous n'avez pas oublié les délégués!).

Bryan ORTIZ
la source
2

(Cette solution n'a été testée que pour Xcode 10 et iOS 12.) Ajoutez une extension pour accéder au champ de texte de la barre de recherche:

extension UISearchBar {
    var textField: UITextField? {
        return subviews.first?.subviews.compactMap { $0 as? UITextField }.first
    }
}

Utilisez ensuite cette propriété pour définir la couleur du texte du champ de texte dans votre barre de recherche:

let searchBar = UISearchBar()
searchBar.textField?.textColor = UIColor.white // or whichever color you want

// ÉDITER

Le code ci-dessus ne fonctionne pas pour iOS 13. Une meilleure façon de gérer cela est d'utiliser:

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 }
    }
}
David Steppenbeck
la source
pour iOS 13, renvoyez subviews.first? .subviews.last? .subviews.compactMap {$ 0 comme? UITextField} .last
Taras
2

// Essayez ce gars

yourSearchbar.searchTextField.textColor = .white
Nrv
la source
2

Swift 5.2 et iOS 13.3.1: -

Ça fonctionne bien.

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]

Dinesh Kumar
la source
1

Voici une version Xamarin.iOS C # de l'approche «find the UITextField». Il ne plantera pas si UITextField disparaît dans la future hiérarchie de vues iOS.

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;
        }
    }
}
t9mike
la source
0

Dans ma situation, la solution est

id appearance = [UITextField appearanceWhenContainedInInstancesOfClasses:@[UISearchBar.class, BCRSidebarController.class]];
[appearance setTextColor:[UIColor.whiteColor colorWithAlphaComponent:0.56]];
poGUIst
la source
0

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
Argus
la source
0

Swift 5:

searchBar[keyPath: \.searchTextField].textColor = UIColor(...)

ramzesenok
la source
0

Dans Swift 5, vous pouvez faire quelque chose comme ci-dessous:

yourSearchBar.searchTextField.textColor = .yourColor
johnDoe
la source
0

Cela a fonctionné pour moi.

    if #available(iOS 13.0, *) {
     searchBar.searchTextField.textColor = .white
    }
Mili
la source
-1

Swift 5 Xcode 11.4 iOS 13.4

    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = .white
    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = .systemFont(ofSize: 13)
blyscuit
la source