24

Here's my code that creates the UIAlertController

    // Create the alert controller
    var alertController = UIAlertController(title: "Are you sure you want to call \(self.number)?", message: "", preferredStyle: .Alert)

    // Create the actions
    var okAction = UIAlertAction(title: "Call", style: UIAlertActionStyle.Default) {
        UIAlertAction in
        var url:NSURL = NSURL(string: "tel://\(self.number)")!
        UIApplication.sharedApplication().openURL(url)
    }

    var cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) {
        UIAlertAction in

    }

    // Add the actions
    alertController.addAction(okAction)
    alertController.addAction(cancelAction)

    // Present the controller
    self.presentViewController(alertController, animated: true, completion: nil)

I can't figure out how to change the text color of the cancel and call actions. The title text is currently black and the cancel and call buttons are white. I'm making to make them all black for better visibility. Any ideas? Thanks!

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
leerob
  • 2,876
  • 1
  • 18
  • 38

10 Answers10

24

After some trial and error, I found this worked. Hopefully this will help future swift newcomers!

alertController.view.tintColor = UIColor.blackColor()
leerob
  • 2,876
  • 1
  • 18
  • 38
  • This worked for me the first time the alert appeared. But after clicking the buttons they changed backed to the default color. From what I've read elsewhere, I think this issue may be new in iOS 9. – peacetype Oct 28 '15 at 22:36
  • Because this does not work in iOS 9, here is a workaround for setting the `tintColor` of a `UIAlertController` button: http://stackoverflow.com/a/32636878/4376309 – peacetype Oct 30 '15 at 21:29
9

Piyush's answer helped me the most, but here are some tweaks for Swift 3 and to change the title and message separately.

Title:

alert.setValue(NSAttributedString(string: alert.message, attributes: [NSFontAttributeName : UIFont.systemFont(ofSize: 29, weight: UIFontWeightMedium), NSForegroundColorAttributeName : UIColor.red]), forKey: "attributedTitle")

Message:

alert.setValue(NSAttributedString(string: alert.message, attributes: [NSFontAttributeName : UIFont.systemFont(ofSize: 29, weight: UIFontWeightMedium), NSForegroundColorAttributeName : UIColor.red]), forKey: "attributedMessage")

The big font size is because I actually needed to do it for tvOS, works great on it and iOS.

CodyMace
  • 646
  • 1
  • 8
  • 19
  • for Title there must be : alert.setValue(NSAttributedString(string: alert.title, attributes: [NSFontAttributeName : UIFont.systemFont(ofSize: 29, weight: UIFontWeightMedium), NSForegroundColorAttributeName : UIColor.red]), forKey: "attributedTitle") – Asmita Oct 17 '19 at 11:02
8

Swift 4.2

One way of doing this is to make extension on UIAlertController, with this all of your app alerts whil have the same tint color. But it leaves destructive actions in red color.

 extension UIAlertController{
        open override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
           self.view.tintColor = .yourcolor
        }
    }
7

Below code is changing the UIAlertView title color.

  let alert = UIAlertController(title: messageTitle, message: messageText, preferredStyle: UIAlertControllerStyle.Alert)

  alert.setValue(NSAttributedString(string: messageTitle, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(17),NSForegroundColorAttributeName : UIColor.redColor()]), forKey: "attributedTitle")

  alert.addAction(UIAlertAction(title: buttonText, style: UIAlertActionStyle.Default, handler: nil))

  parent.presentViewController(alert, animated: true, completion: nil)

If you want to change button color then add following code after present View Controller.

  alert.view.tintColor = UIColor.redColor()
Piyush Sanepara
  • 1,417
  • 2
  • 18
  • 23
3

Here's an update for Swift 4, using Cody's answer as a base:

Setting a colour for the alert title:

alert.setValue(NSAttributedString(string: alert.title!, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 17, weight: UIFont.Weight.medium), NSAttributedStringKey.foregroundColor : UIColor.blue]), forKey: "attributedTitle")

Setting a colour for the alert message:

alert.setValue(NSAttributedString(string: alert.message, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 17, weight: UIFont.Weight.Medium), NSAttributedStringKey.foregroundColor : UIColor.green]), forKey: "attributedMessage")

As per https://developer.apple.com/documentation/foundation/nsattributedstring/key

podomunro
  • 495
  • 4
  • 16
3

In Swift 5 and XCode 11.1 and later, colour for the alert title:

alert.setValue(NSAttributedString(string: alert.title!, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 25, weight: UIFont.Weight.medium), NSAttributedString.Key.foregroundColor : UIColor.red]), forKey: "attributedTitle")

Colour for the alert message:

alert.setValue(NSAttributedString(string: alert.message!, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 20,weight: UIFont.Weight.medium),NSAttributedString.Key.foregroundColor :UIColor.black]), forKey: "attributedMessage")
elarcoiris
  • 1,914
  • 4
  • 28
  • 30
MannaICT13
  • 189
  • 2
  • 9
1

Before iOS 9.0 you could simply change the underlying view's tintColor like this:

alertController.view.tintColor = UIColor.redColor()

However, due to a bug introduced in iOS 9, you can either:

  1. Change the app tintColor in the AppDelegate.

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
        self.window.tintColor = UIColor.redColor()
        return true
    }
    
  2. Reapply the color in the completion block.

    self.presentViewController(alert, animated: true, completion: {() -> Void in
        alert.tintColor = UIColor.redColor()
    })
    

See my other answer here: https://stackoverflow.com/a/37737212/1781087

Community
  • 1
  • 1
guidev
  • 2,695
  • 2
  • 23
  • 44
1

I have faced the same issue and spent a lot of time trying to find the best way to change it's color for iOS 9 and iOS 10 + because it's implemented in a different way.

Finally I have made an extension for UIViewController. In extension I have added custom function which is almost equal to default function "present", but performs fix of colours. Here you are my solution. Applicable for swift 3+, for projects with target starting from iOS 9:

extension UIViewController {
    /// Function for presenting AlertViewController with fixed colors for iOS 9
    func presentAlert(alert: UIAlertController, animated flag: Bool, completion: (() -> Swift.Void)? = nil){
        // Temporary change global colors
        UIView.appearance().tintColor = UIColor.red // Set here whatever color you want for text
        UIApplication.shared.keyWindow?.tintColor = UIColor.red // Set here whatever color you want for text

        //Present the controller
        self.present(alert, animated: flag, completion: {
            // Rollback change global colors
            UIView.appearance().tintColor = UIColor.black // Set here your default color for your application.
            UIApplication.shared.keyWindow?.tintColor = UIColor.black // Set here your default color for your application.
            if completion != nil {
                completion!()
            }
        })
    }
}

To use this fixed function, you should just call this function instead of default present function. Example:

self.presentAlert(alert: alert, animated: true)

Same solution, but for UIActivityViewController:

extension UIViewController {
    /// Function for presenting UIActivityViewController with fixed colors for iOS 9 and 10+
    func presentActivityVC(vc: UIActivityViewController, animated flag: Bool, completion: (() -> Swift.Void)? = nil) {
        // Temporary change global colors for changing "Cancel" button color for iOS 9 and 10+
        if UIDevice.current.systemVersion.range(of: "9.") != nil {
            UIApplication.shared.keyWindow?.tintColor = ColorThemes.alertViewButtonTextColor
        } else {
            UILabel.appearance().textColor = ColorThemes.alertViewButtonTextColor
        }

        self.present(vc, animated: flag) {
            // Rollback for changing global colors for changing "Cancel" button color for iOS 9 and 10+
            if UIDevice.current.systemVersion.range(of: "9.") != nil {
                UIApplication.shared.keyWindow?.tintColor = ColorThemes.tintColor
            } else {
                UILabel.appearance().textColor = ColorThemes.textColorNormal
            }
            if completion != nil {
                completion!()
            }
        }
    }
}

I hope this will help somebody and will save a lot of time. Because my time was not saved by such detailed answer :)

DJ-Glock
  • 1,277
  • 2
  • 12
  • 39
1

Try this

alert.setValue(NSAttributedString(string: alert.message, attributes: [NSFontAttributeName : UIFont.systemFont(ofSize: 29, weight: UIFontWeightMedium), NSForegroundColorAttributeName : UIColor.red]), forKey: "attributedTitle")
Nabeel ali
  • 196
  • 1
  • 5
0
func showAlertOnVC(title: String,btnTitle:String, btnSubTitle:String, message: String, VC: UIViewController? , getcompleted: @escaping((_ confrmation: Bool)-> ())) {
        guard let vc = VC  else {
            return
        }
        let alert = UIAlertController(title: title , message: message, preferredStyle: (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad )  ? .alert : .alert)
        
        alert.view.tintColor = UIColor.green
        let confirmBtn = UIAlertAction(title: btnTitle, style: .default, handler: {_ in
            getcompleted(true)
        })
        let cancelBtn = UIAlertAction(title: btnSubTitle, style: .cancel, handler: {_ in
            getcompleted(false)
        })
        cancelBtn.setValue(UIColor.red, forKey: "titleTextColor")
        alert.addAction(confirmBtn)
        alert.addAction(cancelBtn)
        vc.present(alert, animated: true, completion: nil)
    }
Sasinderan N
  • 77
  • 1
  • 3