How to change UIAlertController button text colour in iOS9?

后端 未结 14 1266
隐瞒了意图╮
隐瞒了意图╮ 2020-12-15 16:16

The question is similar to iOS 8 UIActivityViewController and UIAlertController button text color uses window's tintColor but in iOS 9.

I have a UIAlertControlle

相关标签:
14条回答
  • 2020-12-15 16:44

    In Swift 2.2 you can use following code

     // 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)
    
    0 讨论(0)
  • 2020-12-15 16:45

    In Swift 3.x:

    I found the following to work effectively. I call this at app launch .

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

    So this would change the tint color of all UIAlertViewController button labels in your app globally. The only button label color it doesn't change are those which have a UIAlertActionStyle of destructive.

    0 讨论(0)
  • 2020-12-15 16:52

    I've run into something similar in the past and the issue seems to stem from the fact that the alert controller's view isn't ready to accept tintColor changes before it's presented. Alternatively, try setting the tint color AFTER you present your alert controller:

    [self presentViewController:strongController animated:YES completion:nil];
    strongController.view.tintColor = [UIColor black];
    
    0 讨论(0)
  • 2020-12-15 16:58

    There is a problem with setting the tint color on the view after presenting; even if you do it in the completion block of presentViewController:animated:completion:, it causes a flicker effect on the color of the button titles. This is sloppy, unprofessional and completely unacceptable.

    The one sure-fire way to solve this problem and to do it everywhere, is via adding a category to UIAlertController and swizzling the viewWillAppear.

    The header:

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

    The implementation:

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

    Add a .pch (precompiled header) to your project and include the category:

    #import "UIAlertController+iOS9TintFix.h"
    

    Make sure you register your pch in the project properly, and it will include the category methods in every class that uses the UIAlertController.

    Then, in your app delegates didFinishLaunchingWithOptions method, import your category and call

    [UIAlertController tintFix];
    

    and it will automatically propagate to every single instance of UIAlertController within your app, whether launched by your code or anyone else's.

    This solution works for both iOS 8.X and iOS 9.X and lacks the flicker of the tint change post-presentation approach.

    Mad props to Brandon above for starting this journey, unfortunately my reputation was not sufficient enough to comment on his post, or else I would have left it there!

    0 讨论(0)
  • 2020-12-15 16:59

    Objective-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)
    
    0 讨论(0)
  • 2020-12-15 16:59

    I wanted to make the delete button to appear red, so I used .destructive style:

     alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler:{(UIAlertAction) in
    
    0 讨论(0)
提交回复
热议问题