web-dev-qa-db-fra.com

Comment changer la couleur du texte du bouton UIAlertController dans iOS9?

La question est similaire à iOS 8 La couleur du texte du bouton UIActivityViewController et UIAlertController utilise la teinte de la fenêtre mais dans iOS 9.

J'ai un contrôleur UIAlert et le bouton de renvoi conserve sa couleur blanche même si j'ai essayé de le définir. 

[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blackColor]];

UIAlertController *strongController = [UIAlertController alertControllerWithTitle:title
                                                             message:message
                                                      preferredStyle:preferredStyle];
strongController.view.tintColor = [UIColor black];
24
RayChen

Je suis tombé sur 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 modifications tintColor avant d'être présentée. Sinon, essayez de définir la couleur de teinteAPRÈSvous présentez votre contrôleur d'alertes:

[self presentViewController:strongController animated:YES completion:nil];
strongController.view.tintColor = [UIColor black];
55
dbart

Dans Swift 3.x:

J'ai trouvé ce qui suit pour travailler efficacement. J'appelle cela au lancement de l'application.

UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = UIColor.black

Cela changerait donc la couleur de teinte de toutes les étiquettes de bouton UIAlertViewController dans votre application de manière globale. La seule couleur d'étiquette de bouton qui ne change pas sont ceux qui ont un UIAlertActionStyle destructif.

13
Neil Smith

J'ai pu résoudre ce problème en sous-classant UIAlertController:

class MyUIAlertController: UIAlertController {

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        //set this to whatever color you like...
        self.view.tintColor = UIColor.blackColor()
    }
}

Cela survit à une rotation de l'appareil pendant que l'alerte est affichée. 

Vous n'avez pas non plus besoin de définir la teinte après avoir présenté l'alerte lorsque vous utilisez cette sous-classe.

Bien que cela ne soit pas nécessaire sur iOS 8.4, ce code fonctionne également sur iOS 8.4.

La mise en œuvre d'Objective-C devrait ressembler à ceci:

@interface MyUIAlertController : UIAlertController
@end

@implementation MyUIAlertController
-(void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    //set this to whatever color you like...
    self.view.tintColor = [UIColor blackColor];
}
@end
12
Mike Taverne

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)
11
MAhipal Singh

Il y a un problème avec le réglage de la couleur de teinte sur la vue après la présentation; même si vous le faites dans le bloc d'achèvement de presentViewController: animated: completion:, il provoque un effet de scintillement sur la couleur des titres des boutons. C'est négligé, non professionnel et totalement inacceptable.

Le moyen le plus sûr de résoudre ce problème et de le faire partout est d’ajouter une catégorie à UIAlertController et de survoler 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 oeuvre:

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

Ajoutez un .pch (en-tête précompilé) à votre projet et incluez la catégorie:

#import "UIAlertController+iOS9TintFix.h"

Assurez-vous d'enregistrer correctement votre ordinateur dans le projet, qui inclura les méthodes de catégorie dans chaque classe qui utilise UIAlertController.

Ensuite, dans la méthode didFinishLaunchingWithOptions de votre application, importez votre catégorie et appelez

[UIAlertController tintFix];

et il se propagera automatiquement à chaque instance d'UIAlertController au sein de votre application, qu'elle soit lancée par votre code ou celle de quelqu'un d'autre.

Cette solution fonctionne à la fois pour iOS 8.X et iOS 9.X et n'a pas le scintillement de l'approche de changement de teinte après la présentation.

Les accessoires fous à Brandon ci-dessus pour avoir commencé ce voyage, malheureusement, ma réputation n'était pas suffisante pour commenter son message, sinon je l'aurais laissé là!

4
ObiDan
[[UIView appearance] setTintColor:[UIColor black]];  

cela changera toutes les vues de UIView tintColor ainsi que de UIAlertController

3
lin

Swift3

J'ai essayé d'utiliser UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = MyColor, mais cela évite d'autres éléments non liés à la configuration UIAlertController from from tintColor. Je l'ai vu en essayant de changer la couleur des éléments des boutons de la 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
}
}
3
Mike M

J'ai trouvé une solution à cela. Pas une solution élégante, mais une solution.

J'ai balayé viewWillAppear: sur UIAlertController, puis j'ai parcouru les vues et modifié la couleur de la teinte. Dans mon cas, une teinteCouleur était définie sur toute la fenêtre et malgré le réglage de la teinteCouleur via l'apparence, UIAlertController conservait la couleur de la fenêtre. Je vérifie si la couleur est égale à celle de la fenêtre et, le cas échéant, en applique une nouvelle. Si vous appliquez aveuglément la teinteCouleur à toutes les vues, la teinte rouge des actions destructives sera réinitialisée.

+ (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];  
    }  
}  

Toutefois, cela ne fonctionne pas sur iOS 8 et vous devrez donc définir la couleur de teinte d’apparence.

[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor greenColor]];  
2

Vous pouvez le changer en utilisant: Swift 3.x

    strongController.view.tintColor = UIColor.green
2
Dheeraj D

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)
1
Mohsin Qureshi

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()
}))
0
Ferran Maylinch

Je voulais faire apparaître le bouton de suppression en rouge. J'ai donc utilisé le style .destructive:

 alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler:{(UIAlertAction) in
0
fullMoon

Le moyen le plus raisonnable est de définir la teinte de la fenêtre principale. Nous avons généralement besoin d'apparences uniformes.

// in app delegate
window.tintColor = ...

D'autres solutions ont des défauts

  • Utiliser l'apparence

    UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = ...
    

    Ne fonctionne pas sur iOS 9, teste avec iOS 11 SDK.

    [[UIView appearance] setTintColor:[UIColor black]];  
    

    Es-tu sérieux?

  • Définissez la couleur de la vue UIAlertController est instable. La couleur peut changer lorsque l'utilisateur appuie sur le bouton ou après l'affichage de la vue.

  • La méthode de sous-classe UIAlertController et d’écriture est une méthode de piratage inacceptable.

0
BB9z