Bcf Ant
Bcf Ant

Reputation: 1749

UIAlertController tint color defaults to blue on highlight

I'm using the following code to present a UIAlertController action sheet with the item text as red. I've used the tint property to set the color.

UIAlertController *alertController = [UIAlertController
                                      alertControllerWithTitle:nil
                                      message:nil
                                      preferredStyle:UIAlertControllerStyleActionSheet];
alertController.view.tintColor = [UIColor redColor];

The text color seems to be defaulting to blue on highlight or selection. Is this normal and how do I stop this?

Upvotes: 34

Views: 20866

Answers (11)

Ben M
Ben M

Reputation: 2475

Update for Swift 4, Xcode 9

private static func setupAppearanceForAlertController() {
    let view = UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self])
    view.tintColor = .black
}

Upvotes: 11

Alexander
Alexander

Reputation: 770

Just change your view tintAdjustmentMode to UIViewTintAdjustmentModeNormal, so it will not change it's color on dimm.

Upvotes: 1

Frederik Winkelsdorf
Frederik Winkelsdorf

Reputation: 4573

This is a known Bug, see https://openradar.appspot.com/22209332

To fix it, reapply the tint color in the Completion handler. Here's my Swift Solution, you will be able to adapt it easily for ObjC:

alertController.view.tintColor = UIColor.redColor() // apply 1st time to prevent flicker from Blue to Red when displaying

navigationController?.presentViewController(alertController, animated: true, completion: {
    // Bugfix: iOS9 - Tint not fully Applied without Reapplying
    alertController.view.tintColor = UIColor.redColor()
})

One Note: This does not fix the Bug entirely. You will notice upon Device Rotation that the Buttons are recolored with System Default (= Blue) tint.

Expect it to be fixed with iOS 9.1.

Edit 10/23/2015: Still not fixed with iOS 9.1. Retested with iOS 9.1 + Xcode 7.1 (7B91B) released a couple of days ago. As of now setting the .tintColor does not work, however as commented you can set the tintColor of the whole Application, e.g. in AppDelegate didFinishLaunchingWithOptions set window?.tintColor = UIColor.redColor(). This also tints the AlertController Buttons but may not be suitable in some cases as this tint is applied throughout the whole Application.

Upvotes: 50

Kaushik Movaliya
Kaushik Movaliya

Reputation: 857

You can change button colour like this

UIAlertAction* button = [UIAlertAction
                              actionWithTitle:@"Delete Profile"
                              style:UIAlertActionStyleDefault
                              handler:^(UIAlertAction * action)
                              {
                                  //Add Action.
                              }];
[button setValue:[UIColor redColor] forKey:@"titleTextColor"];

By Using this line [button setValue:[UIColor redColor] forKey:@"titleTextColor"]; You can change the button colour of your action sheet

Upvotes: 5

Michael
Michael

Reputation: 9894

To set custom color and font subclass UIAlertController like this.

import UIKit

class StyledAlertController: UIAlertController {

    private var cancelText:String?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.tintColor = YourColor
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        findLabel(view)
    }

    private func findLabel(scanView: UIView!) {
        if (scanView.subviews.count > 0) {
            for subview in scanView.subviews {
                if let label:UILabel = subview as? UILabel {
                    if (cancelText != nil && label.text == cancelText!) {
                        dispatch_async(dispatch_get_main_queue(),{
                            label.textColor = YourColor
                            label.tintColor = YourColor
                        })
                    }
                    let font:UIFont = UIFont(name: YourFont, size: label.font!.pointSize)!
                    label.font = font
                }
                findLabel(subview)
            }
        }
    }
}

Use like this (as you normally would)

let StyledAlertController = StyledAlertController(title: "My Title", message: "My Message", preferredStyle: .ActionSheet)

let cancelAction:UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
        print("Cancel Action Click")
    }
actionSheetController.addAction(cancelAction)

let anotherAction:UIAlertAction = UIAlertAction(title: "Another Action", style: .Default) { action -> Void in
        print("Another Action Click")
    }
actionSheetController.addAction(anotherAction:UIAlertAction)

presentViewController(actionSheetController, animated: true, completion: nil)

Upvotes: 1

laynemoseley
laynemoseley

Reputation: 258

Set your tint color in traitCollectionDidChange in a subclass of UIAlertController.

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    self.view.tintColor = UIColor.redColor()
}

Upvotes: 2

marco v berlo
marco v berlo

Reputation: 151

You can also change the app tint color in appdelegate.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window.tintcolor = [UIColor yellowColor];
    return YES;
}

works perfect for me.

Upvotes: 15

Darko
Darko

Reputation: 9845

To prevent the fast "popping up" of the new tint color the alpha value of the alert controller can be animated. Then it looks exactly the same as if there where no bug:

    alertController.view.alpha = 0.0
    presentViewController(alertController, animated: false) {
        alertController.view.tintColor = UIColor.redColor()
        UIView.animateWithDuration(0.2, animations: { alertController.view.alpha = 1.0 }, completion: nil)
    }

Upvotes: 0

G.Hakobyan
G.Hakobyan

Reputation: 1

UIAlertController is availabel iOS 8 and later , thus there is a bug for devices with older version. There's no problem for devices with corresponding or higher version.

Upvotes: 0

Eddy
Eddy

Reputation: 407

Just add the tintColor after the presentViewController. Works on iOS 9.0.2

[self presentViewController:alertController animated:YES completion:nil];

[alertController.view setTintColor:[UIColor yellowColor]];

Upvotes: 39

Vinay Jain
Vinay Jain

Reputation: 1661

I am still confused what you want to achieve. But you can try the Apple's way of creating Destructive buttons(by default text color is red).

The code where you are creating UIAlertActions don't use the Default style for the buttons you want in red color. Instead use UIAlertActionStyleDestructive. Sample Code :

UIAlertAction* cancel = [UIAlertAction
                         actionWithTitle:@"Cancel"
                         style:UIAlertActionStyleDestructive
                         handler:^(UIAlertAction * action)
                         {
                             [view dismissViewControllerAnimated:YES completion:nil];

                         }];

Upvotes: 0

Related Questions