Comment changer la couleur du texte du bouton UIAlertController dans iOS9?
la question est similaire à iOS 8 UIActivityViewController et UIAlertController bouton text color utilise tintColor de la fenêtre mais dans iOS 9.
j'ai un Controller UIAlertController et le bouton de suppression garde la couleur blanche même si j'ai essayé de mettre
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blackColor]];
UIAlertController *strongController = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:preferredStyle];
strongController.view.tintColor = [UIColor black];
13 réponses
j'ai rencontré quelque chose de similaire dans le passé et le problème semble provenir du fait que la vue du contrôleur d'alerte n'est pas prête à accepter les changements tintColor
avant qu'ils ne soient présentés. Alternativement, essayez de définir la couleur de teinte après vous présentez votre contrôleur d'alerte:
[self presentViewController:strongController animated:YES completion:nil];
strongController.view.tintColor = [UIColor black];
j'ai pu résoudre cela en sous-classant UIAlertController
:
class MyUIAlertController: UIAlertController {
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//set this to whatever color you like...
self.view.tintColor = UIColor.blackColor()
}
}
ceci survit à une rotation de l'appareil pendant que l'alerte apparaît.
vous n'avez pas non plus besoin de régler le tintColor après avoir présenté l'alerte lors de l'utilisation de la présente sous-classe.
bien qu'il ne soit pas nécessaire sur iOS 8.4, ce code fonctionne aussi sur iOS 8.4.
la mise en œuvre de L'Objectif C devrait être quelque chose comme ceci:
@interface MyUIAlertController : UIAlertController
@end
@implementation MyUIAlertController
-(void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
//set this to whatever color you like...
self.view.tintColor = [UIColor blackColor];
}
@end
Dans Swift 3.x:
j'ai trouvé ce qui suit pour travailler efficacement. J'appelle ça au lancement de l'application .
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = UIColor.black
ainsi cela changerait la couleur de teinte de toutes les étiquettes de bouton uialertviewcontroller dans votre app globalement. La seule couleur d'étiquette de bouton qu'il ne change pas sont ceux qui ont un UIAlertActionStyle de destructive.
"Objectif-C
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title text" message:@"Message text" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
//code here…
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Later" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
//code here….
}];
[ok setValue:[UIColor greenColor] forKey:@"titleTextColor"];
[cancel setValue:[UIColor redColor] forKey:@"titleTextColor"];
[alertController addAction:ok];
[alertController addAction:cancel];
[alertController.view setTintColor:[UIColor yellowColor]];
[self presentViewController:alertController animated:YES completion:nil];
Swift 3
let alertController = UIAlertController(title: "Title text", message: "Message text", preferredStyle: .alert)
let ok = UIAlertAction(title: "Yes" , style: .default) { (_ action) in
//code here…
}
let cancel = UIAlertAction(title: "Later" , style: .default) { (_ action) in
//code here…
}
ok.setValue(UIColor.green, forKey: "titleTextColor")
cancel.setValue(UIColor.red, forKey: "titleTextColor")
alertController.addAction(ok)
alertController.addAction(cancel)
alertController.view.tintColor = .yellow
self.present(alertController, animated: true, completion: nil)
il y a un problème avec le réglage de la teinte sur la vue après présentation; même si vous le faites dans le bloc d'achèvement de presentViewController:animated:completion:, il provoque un effet de clignotement sur la couleur des titres de bouton. C'est bâclée, non professionnel et totalement inacceptable.
le seul moyen sûr-feu de résoudre ce problème et de le faire partout, est par l'ajout d'une catégorie à UIAlertController et swizzling le viewWillAppear.
L'en-tête:
//
// UIAlertController+iOS9TintFix.h
//
// Created by Flor, Daniel J on 11/2/15.
//
#import <UIKit/UIKit.h>
@interface UIAlertController (iOS9TintFix)
+ (void)tintFix;
- (void)swizzledViewWillAppear:(BOOL)animated;
@end
La mise en œuvre:
//
// UIAlertController+iOS9TintFix.m
//
// Created by Flor, Daniel J on 11/2/15.
//
#import "UIAlertController+iOS9TintFix.h"
#import <objc/runtime.h>
@implementation UIAlertController (iOS9TintFix)
+ (void)tintFix {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method method = class_getInstanceMethod(self, @selector(viewWillAppear:));
Method swizzle = class_getInstanceMethod(self, @selector(swizzledViewWillAppear:));
method_exchangeImplementations(method, swizzle);});
}
- (void)swizzledViewWillAppear:(BOOL)animated {
[self swizzledViewWillAppear:animated];
for (UIView *view in self.view.subviews) {
if (view.tintColor == self.view.tintColor) {
//only do those that match the main view, so we don't strip the red-tint from destructive buttons.
self.view.tintColor = [UIColor colorWithRed:0.0 green:122.0/255.0 blue:1.0 alpha:1.0];
[view setNeedsDisplay];
}
}
}
@end
ajouter A.pch (en-tête précompilé) à votre projet et inclure la catégorie:
#import "UIAlertController+iOS9TintFix.h"
assurez-vous d'inscrire correctement votre pch dans le projet, et il inclura les méthodes de catégorie dans chaque classe qui utilise le contrôleur UIAlertController.
puis, dans votre application, les délégués ont fini par lancer la méthode des options, importer votre catégorie et appel
[UIAlertController tintFix];
et il se propagera automatiquement à chaque instance de UIAlertController dans votre application, qu'elle soit lancée par votre code ou celui de quelqu'un d'autre.
Cette solution fonctionne pour les deux iOS 8.X et iOS 9.X et n'a pas le scintillement de l'approche du changement de teinte après la présentation.
Mad props à Brandon ci-dessus pour commencer ce voyage, malheureusement, ma réputation n'était pas suffisant pour le commentaire sur son poteau, sinon je l'aurais laissé là!
[[UIView appearance] setTintColor:[UIColor black]];
cela va changer tous les UIView tintColor
ainsi que UIAlertController
'
swift3
a essayé d'utiliser UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = MyColor
mais cela empêche d'autres articles sans rapport avec UIAlertController
de la configuration de tintColor. Je l'ai vu en essayant de changer la couleur des éléments de barre de navigation.
je suis passé à une extension (basée sur la réponse de Mike Taverne ci-dessus) et cela fonctionne très bien.
extension UIAlertController {
override open func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//set this to whatever color you like...
self.view.tintColor = MyColor
}
}
j'ai trouvé une solution. Pas une solution élégante, mais une solution.
je swizzled viewWillAppear: sur UIAlertController, puis en boucle à travers les points de vue et modifié la teinte de la couleur. Dans mon cas, j'ai eu un colorimètre réglé sur la fenêtre entière et malgré le réglage du colorimètre via l'apparence, le contrôleur UIAlertController a maintenu la couleur sur la fenêtre. Je vérifie si la couleur est égale à celle de la fenêtre et si oui appliquer une nouvelle. Appliquer aveuglément le tintColor à tous les vues donneront une teinte rouge sur les actions destructrices à réinitialiser.
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method swizzleMethod = class_getInstanceMethod(self, @selector(viewWillAppear:));
Method method = class_getInstanceMethod(self, @selector(alertSwizzle_viewWillAppear:));
method_exchangeImplementations(method, swizzleMethod);
});
}
- (void)alertSwizzle_viewWillAppear:(BOOL)animated
{
[self alertSwizzle_viewWillAppear:animated];
[self applyTintToView:self.view];
}
- (void)applyTintToView:(UIView *)view
{
UIWindow *mainWindow = [UIApplication sharedApplication].keyWindow;
for (UIView *v in view.subviews) {
if ([v.tintColor isEqual:mainWindow.tintColor]) {
v.tintColor = [UIColor greenColor];
}
[self applyTintToView:v];
}
}
cependant cela ne fonctionne pas sur iOS 8, donc vous aurez toujours besoin de définir la couleur de teinte apparente.
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor greenColor]];
dans Swift 2.2 vous pouvez utiliser le code suivant
// LogOut or Cancel
let logOutActionSheet: UIAlertController = UIAlertController(title: "Hello Mohsin!", message: "Are you sure you want to logout?", preferredStyle: .Alert)
self.presentViewController(logOutActionSheet, animated: true, completion: nil)
let cancelActionButton: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
print("Cancel Tapped")
}
logOutActionSheet.addAction(cancelActionButton)
let logOutActionButton: UIAlertAction = UIAlertAction(title: "Clear All", style: .Default)
{ action -> Void in
//Clear All Method
print("Logout Tapped")
}
logOutActionButton.setValue(UIColor.redColor(), forKey: "titleTextColor")
logOutActionSheet.addAction(logOutActionButton)
vous pouvez le changer en utilisant: Swift 3.x
strongController.view.tintColor = UIColor.green
vous avez 3 styles pour les boutons d'action:
let style : UIAlertActionStyle = .default
// default, cancel (bold) or destructive (red)
let alertCtrl = UIAlertController(....)
alertCtrl.addAction( UIAlertAction(title: "click me", style: style, handler: {
_ in doWhatever()
}))
je voulais faire apparaître le bouton Supprimer en rouge, donc j'ai utilisé .destructive style:
alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler:{(UIAlertAction) in
la façon la plus raisonnable est de régler le tintColor de la fenêtre principale. Comme une apparence uniforme est ce que nous avons habituellement besoin.
// in app delegate
window.tintColor = ...
autres solutions présentant des défauts
-
Use apparence
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = ...
ne fonctionne pas sur iOS 9, tests avec IOS 11 SDK.
[[UIView appearance] setTintColor:[UIColor black]];
Êtes-vous sérieux?
-
Set UIAlertController vue de la nuance de couleur est instable. La couleur peut changer lorsque l'utilisateur presse le bouton ou après la disposition de l'affichage.
-
sous-classe UIAlertController et de remplacer la méthode de présentation est hack manière qui est inacceptable.