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?
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
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
Vous pouvez définir la couleur du texte par
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor blueColor]];
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]}];
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;
}
}
}
}
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];
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]}];
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
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
}
}
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.
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.
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
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.
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()
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;
}
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.