web-dev-qa-db-fra.com

Changement de couleur du texte UISearchBar dans iOS 7

Comment changer la couleur du texte de UISearchBar dans iOS 7?

Dans iOS 6, je sous-classais la UISearchBar et dans layoutSubviews la personnalisation des propriétés de la sous-vue UITextField de UISearchBar

Mais dans iOS 7, UISearchBar n'a pas UITextField comme sous-vue. Comment régler ceci?

50
Gaurang

Dans iOS 7 pour accéder à Text Field, vous devez répéter au niveau supérieur. Changez votre code comme ça

for (UIView *subView in self.searchBar.subviews)
{
    for (UIView *secondLevelSubview in subView.subviews){
        if ([secondLevelSubview isKindOfClass:[UITextField class]])
        {
            UITextField *searchBarTextField = (UITextField *)secondLevelSubview;

            //set font color here
            searchBarTextField.textColor = [UIColor blackColor];

            break;
        }
    }
}

Note: Ceci n'est pas une API publique

OU

Vous pouvez utiliser la propriété apparence de UIControls, comme

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];

Remarque: le proxy d'apparence peut être utilisé pour iOS 9.0 + OutPut

enter image description here

Vous pouvez définir la tintcolor pour qu’elle s’applique aux éléments clés du search bar.

Utilisez tintColor pour teinter les éléments de premier plan.

Utilisez barTintColor pour teinter l’arrière-plan de la barre.

Dans iOS v7.0, toutes les sous-classes d'UIView dérivent leur comportement pour tintColor de la classe de base. Voir la discussion sur tintColor au niveau UIView pour plus d’informations . Apple Doc

104
Toseef Khilji

Vous pouvez définir la couleur du texte par

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor blueColor]];
95
Sandeep-Systematix

Pour XCode 6 (iOS8 SDK), les opérations suivantes NE FONCTIONNENT PAS

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor redColor]];

Mais ce qui suit fonctionne (pour le déploiement sur iOS7 et iOS8)

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
35
Graham Dawson

S'il est vrai que le protocole UIAppearance est une "API publique", ce n'est pas vrai qu'ITUextField le supporte. 

Si vous jetez un coup d'oeil à UITextField.h et cherchez la chaîne "UI_APPEARANCE_SELECTOR", vous verrez qu'il ne contient aucune occurrence de cette chaîne. Si vous examinez UIButton, vous en trouvez plusieurs: il s'agit de toutes les propriétés officiellement prises en charge par l'API UIAppearance. Il est un peu connu que UITextField n'est pas pris en charge par l'API UIAppearance. Le code dans la réponse de Sandeep ne fonctionnera pas toujours et ce n'est en fait pas la meilleure approche. 

Ceci est un article utile avec des liens utiles: http://forums.xamarin.com/discussion/175/uitextfield-appearance

La bonne approche est malheureusement désordonnée - parcourez les sous-vues (ou les sous-vues de la sous-vue principale pour iOS7) et définissez-la manuellement. Sinon, vous aurez des résultats peu fiables. Mais vous pouvez simplement créer une catégorie pour UISearchBar et ajouter une méthode de couleur setTextColor: (UIColor *). Exemple:

- (void)setTextColor:(UIColor*)color
{
    for (UIView *v in self.subviews)
    {
        if([Environment isVersion7OrHigher]) //checks UIDevice#systemVersion               
        {
            for(id subview in v.subviews)
            {
                if ([subview isKindOfClass:[UITextField class]])
                {
                    ((UITextField *)subview).textColor = color;
                }
            }
        }

        else
        {
            if ([v isKindOfClass:[UITextField class]])
            {
                ((UITextField *)v).textColor = color;
            }
        }
    }
}
5
Jordan Snyder

Attention: Cela devrait entraîner le rejet de l'application!

KVC FTW. Cela l'a fait pour moi. 

UITextField *searchField = [self.searchBar valueForKey:@"_searchField"];
searchField.textColor = [UIColor redColor];
5
Matthieu Riegler

Vous pouvez définir les attributs de texte comme suit

[[UITextField appearanceWhenContainedIn:[<YOUR_CONTROLLER_NAME> class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor], NSFontAttributeName:[UIFont systemFontOfSize:14.0]}];
4
mOp

Cela semble être la bonne réponse https://stackoverflow.com/a/19315895/2493073

La version Swift de celui-ci est:

UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).textColor = UIColor.blueColor()

Ceci ne fonctionnerait que pour iOS 9.0. Afin de le faire fonctionner pour les versions inférieures, vous devrez suivre cette question. https://stackoverflow.com/a/27807417/2493073

4
Fernando Mata

Swift Extension

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
    }
}
4
Adam Waite

Voici un exemple de travail réalisé en C # avec Xamarin:

SearchBar = new UISearchBar ();
foreach (var subView in SearchBar.Subviews) {
    foreach (var field in subView.Subviews) {
        if (field is UITextField) {
            UITextField textField = (UITextField)field;
            textField.TextColor = UIColor.White;
        }
    }
}

J'espère que ça aide quelqu'un.

4
Robert Lawson

Dans mon cas, j'ai plusieurs objets UISearchBar et ils doivent changer la couleur de la police textField. appearanceWhenContainedIn met à jour un comportement UISearchBar, mais un autre ne le fait pas.

Je sous-classe le UISearchBar et implémenter -(id)initWithFrame: personnalisé comme suit, et cela fonctionne.

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.searchBarStyle       = UISearchBarStyleMinimal;
        self.tintColor            = [UIColor whiteColor];
        self.barTintColor         = [UIColor whiteColor];

        [[UITextField appearanceForTraitCollection:self.traitCollection whenContainedIn:[self class], nil] setDefaultTextAttributes:
         @{
           NSForegroundColorAttributeName : [UIColor whiteColor]
           }];
    }
    return self;
}

Référence du protocole UIAppearance a déclaré que,

En d'autres termes, la déclaration de confinement dans apparenceWhenContainedIn: est traitée comme une commande partielle. Donné un ordre concret (hiérarchie de sous-vues réelle), UIKit sélectionne le commande partielle qui est la première correspondance unique lors de la lecture du fichier hiérarchie réelle de la fenêtre vers le bas.

Donc, appearanceWhenContainedIn: ne traitera pas toutes les UISearchBar dans la hiérarchie de UIWindow. Et cela suggère cela.

Utilisez l’apparenceForTraitCollection: et apparenceForTraitCollection: whenContainedIn: méthodes pour extraire le fichier proxy pour une classe avec la collection de traits spécifiée.

2
AechoLiu

vous pouvez utiliser la barre de recherche à l'intérieur du champ de texte

 UISearchBar *  searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 50, 320, 44) ];
searchBar.autocorrectionType = UITextAutocapitalizationTypeWords;
searchBar.delegate = self;
searchBar.searchBarStyle = UISearchBarStyleMinimal;
searchBar.barTintColor = [UIColor redColor];
[[UITextField appearanceWhenContainedIn:[searchBar class], nil]setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
[self.view addSubview:searchBar];

Mise à jour dans Swift 3

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.black
1
Ben

Le moyen le plus simple de le faire est de mettre ce code dans viewDidAppear ou viewWillAppear :

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];

Cela fonctionne dans iOS 8 et Xcode 6 , contrairement à certains autres codes. Cela peut déranger la police et la taille du texte, etc., mais vous pouvez le modifier dans les attributs de texte.

Cela change la couleur du texte pour tout barres de recherche dans votre application. Si vous souhaitez seulement en changer un, utilisez le code ci-dessus, puis dans toute autre vue avec une barre de recherche, utilisez le même code, mais définissez la couleur comme vous le souhaitez.

1
Jack Solomon

Cette classe vous donnera un contrôle total sur chaque élément de la UISearchBar


import UIKit

class SMTSearchBar: UISearchBar {

    override init(frame: CGRect) {
        super.init(frame: frame)
        initialize()
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        initialize()
    }

    convenience init() {
        self.init(frame: CGRectZero)
        initialize()
    }

    // Style the view
    func initialize() {

        // Search Area
        let searchField = valueForKey("searchField") as! UITextField
        searchField.textColor = Colors.White
        searchField.font = UIFont(name: Fonts.MuseoSans500, size: 16)
        searchField.backgroundColor = Colors.Black.colorWithAlphaComponent(0.1)

        // Icons
        let searchIcon = UIImage(named: Icons.Search)?.imageWithTint(Colors.White)
        let smallClearIconNormal = UIImage(named: Icons.SmallClear)?.imageWithTint(Colors.White)
        let smallClearIconHighLight = UIImage(named: Icons.SmallClear)?.imageWithTint(Colors.White.colorWithAlphaComponent(0.5))
        setImage(searchIcon, forSearchBarIcon: .Search, state: .Normal)
        setImage(smallClearIconHighLight, forSearchBarIcon: .Clear, state: .Highlighted)
        setImage(smallClearIconNormal, forSearchBarIcon: .Clear, state: .Normal)
    }

    func setPlaceHolder(placeholder: String) {
        for subView in subviews{
            for subsubView in subView.subviews {
                if let textField = subsubView as? UITextField {
                    textField.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSForegroundColorAttributeName: Colors.White.colorWithAlphaComponent(0.5)])
                }
            }
        }
    }
}

Utilisation (dans la barre de navigation)

let searchBar:SMTSearchBar = SMTSearchBar()
searchBar.sizeToFit()
searchBar.setPlaceHolder("Search for cool things")
navigationItem.titleView = searchBar
searchBar.becomeFirstResponder()
0
Michael

Même si j'aurais préféré utiliser une API d'apparence, cela ne fonctionnait pas avec iOS8. Voici la solution la moins compliquée avec laquelle je suis venu:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if (self.shouldEnableSearchBar)
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^
        {
            UITextField *searchBarTextField = [[AFPBaseViewController findSubviewsOfView:self.searchBar ofClass:[UITextField class]] firstObject];
            searchBarTextField.textColor = AFPConstantsColorGold;
        });
    }

}

Vous pourriez peut-être même créer une catégorie UIView avec cela. La raison pour laquelle cela doit être appelé dans viewDidAppear est que UISearchBar est en réalité contenu dans un ViewController et qu'il ne charge pas toutes ses sous-vues avant son affichage à l'écran. Il pourrait également être ajouté dans viewWillAppear, mais je ne l’ai pas testé.

+ (NSArray *)findSubviewsOfView:(UIView *)view ofClass:(Class)class
{
    NSMutableArray *targetSubviews = [NSMutableArray new];
    for (id subview in view.subviews)
    {
        if ([subview isKindOfClass:class])
        {
            [targetSubviews addObject:subview];
        }

        if ([subview subviews].count)
        {
            [targetSubviews addObjectsFromArray:[self findSubviewsOfView:subview ofClass:class]];
        }
    }
    return targetSubviews.copy;
}
0
mmackh

C'est la bonne solution pour iOS8:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:14], NSForegroundColorAttributeName:[UIColor lightGrayColor]}];

Vous devez également définir la police, sinon la taille de la police sera incorrecte.

0
Marius