20

Ok so I have this alert that I am using and I want the background of it to be black not grey like it is. I have managed to change the colour of the text for the title and the message but not the background colour. Well to the desired colour I want. I have changed it to green blue and white, but not black. When I try to change it to black it turns grey. Any suggestions will help and be appreciated. I tried this here How to change the background color of the UIAlertController? and that is how I got to where I am now.

Here is what I have going now:

func showAlert(title:String, message:String) {

    //Set up for the title color
    let attributedString = NSAttributedString(string: title, attributes: [
        NSFontAttributeName : UIFont.systemFontOfSize(15), //your font here,
        NSForegroundColorAttributeName : UIColor.whiteColor()
        ])
    //Set up for the Message Color
    let attributedString2 = NSAttributedString(string: message, attributes: [
        NSFontAttributeName : UIFont.systemFontOfSize(15), //your font here,
        NSForegroundColorAttributeName : UIColor.whiteColor()
        ])

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

    alert.setValue(attributedString, forKey: "attributedTitle")
    alert.setValue(attributedString2, forKey: "attributedMessage")
    //alert.view.tintColor = UIColor.whiteColor()
    let dismissAction = UIAlertAction(title: "Dismiss", style: .Destructive, handler: nil)
        alert.addAction(dismissAction)
    self.presentViewController(alert, animated: true, completion: nil)
    //set the color of the Alert
    let subview = alert.view.subviews.first! as UIView
    let alertContentView = subview.subviews.first! as UIView
    alertContentView.backgroundColor = UIColor.blackColor()
    //alertContentView.backgroundColor = UIColor.greenColor()
    //Changes is to a grey color :( 
    /*
    alertContentView.backgroundColor = UIColor(
        red: 0,
        green: 0,
        blue: 0,
        alpha: 1.0)
    //Also another Grey Color Not batman black
    */

    //alertContentView.backgroundColor = UIColor.blueColor()
    //turns into a purple



}
Community
  • 1
  • 1
MNM
  • 2,673
  • 6
  • 38
  • 73
  • 1
    @LucaDavanzo that is actually how I got to this spot. If you look at my code its is the exact same as one of the suggestions – MNM May 18 '16 at 08:50

8 Answers8

34

Swift 4.1 :

This is the best way works for me :

func testAlert(){
    let alert = UIAlertController(title: "Let's See ..",message: "It Works!", preferredStyle: .alert)
    let dismissAction = UIAlertAction(title: "Dismiss", style: .default, handler: nil)

    // Accessing alert view backgroundColor :
    alert.view.subviews.first?.subviews.first?.subviews.first?.backgroundColor = UIColor.green

    // Accessing buttons tintcolor :
    alert.view.tintColor = UIColor.white

    alert.addAction(dismissAction)
    present(alert, animated: true, completion:  nil)
}

Test Image

cs4alhaider
  • 1,318
  • 1
  • 17
  • 26
24

try this

Swift2 and below

let subview :UIView = alert.view.subviews. first! as UIView
let alertContentView = subview.subviews. first! as UIView
alertContentView.backgroundColor = UIColor.blackColor()

Objective -C

UIView *subView = alertController.view.subviews.firstObject; //firstObject
UIView *alertContentView = subView.subviews.firstObject; //firstObject
[alertContentView setBackgroundColor:[UIColor darkGrayColor]];

alertContentView.layer.cornerRadius = 5;

updated answer swift 3 and above

   let alert = UIAlertController(title: "validate",message: "Check the process", preferredStyle: .alert)
    let dismissAction = UIAlertAction(title: "Dismiss", style: .destructive, handler: nil)
    alert.addAction(dismissAction)
    self.present(alert, animated: true, completion:  nil)
    // change the background color
    let subview = (alert.view.subviews.first?.subviews.first?.subviews.first!)! as UIView
    subview.layer.cornerRadius = 1
    subview.backgroundColor = UIColor(red: (195/255.0), green: (68/255.0), blue: (122/255.0), alpha: 1.0)

output

iPhone

enter image description here

iPad

enter image description here

Anbu.Karthik
  • 82,064
  • 23
  • 174
  • 143
  • 1
    @Anbu.Karthik the objective c code that you have provided not working for me. `UIView *subView = alertController.view.subviews.lastObject; UIView *alertContentView = subView.subviews.lastObject; [alertContentView setBackgroundColor:[UIColor darkGrayColor]]; alertContentView.layer.cornerRadius = 10;` Stil the background color remains as white. – Aneesh Jan 05 '17 at 07:17
  • No longer working. The invisible corners get now the colour instead of background. – Houman May 13 '18 at 10:58
  • @Aneesh - use `firstObject` instead of `lastObject` – Anbu.Karthik May 18 '18 at 03:52
  • 1
    Messing around in the subviews of `UIAlertController ` is bound to fail eventually. – Mojo66 Sep 29 '18 at 20:38
  • What in the world is this: "alert.view.subviews.first?.subviews.first?.subviews.first!" I refuse to submit such code to Apple or any employer :/ –  Dec 23 '18 at 04:38
9

Swift 5
Write just one line of code using UIAlertController extension.

alertController.setBackgroundColor(color: UIColor.black)

Full documentation: http://www.swiftdevcenter.com/change-font-text-color-and-background-color-of-uialertcontroller/

extension UIAlertController {

    //Set background color of UIAlertController
    func setBackgroundColor(color: UIColor) {
        if let bgView = self.view.subviews.first, let groupView = bgView.subviews.first, let contentView = groupView.subviews.first {
            contentView.backgroundColor = color
        }
    }

    //Set title font and title color
    func setTitlet(font: UIFont?, color: UIColor?) {
        guard let title = self.title else { return }
        let attributeString = NSMutableAttributedString(string: title)//1
        if let titleFont = font {
            attributeString.addAttributes([NSAttributedString.Key.font : titleFont],//2
                                          range: NSMakeRange(0, title.utf8.count))
        }

        if let titleColor = color {
            attributeString.addAttributes([NSAttributedString.Key.foregroundColor : titleColor],//3
                                          range: NSMakeRange(0, title.utf8.count))
        }
        self.setValue(attributeString, forKey: "attributedTitle")//4
    }

    //Set message font and message color
    func setMessage(font: UIFont?, color: UIColor?) {
        guard let message = self.message else { return }
        let attributeString = NSMutableAttributedString(string: message)
        if let messageFont = font {
            attributeString.addAttributes([NSAttributedString.Key.font : messageFont],
                                          range: NSMakeRange(0, message.utf8.count))
        }

        if let messageColorColor = color {
            attributeString.addAttributes([NSAttributedString.Key.foregroundColor : messageColorColor],
                                          range: NSMakeRange(0, message.utf8.count))
        }
        self.setValue(attributeString, forKey: "attributedMessage")
    }

    //Set tint color of UIAlertController
    func setTint(color: UIColor) {
        self.view.tintColor = color
    }
}
Ashish Chauhan
  • 1,316
  • 15
  • 22
5

For Objective C, the below code works like charm.

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Save changes?" message:nil preferredStyle:UIAlertControllerStyleAlert];

UIView *firstSubview = alertController.view.subviews.firstObject;

UIView *alertContentView = firstSubview.subviews.firstObject;

for (UIView *subSubView in alertContentView.subviews) { //This is main catch
    subSubView.backgroundColor = [UIColor blueColor]; //Here you change background
}
R. Mohan
  • 2,182
  • 17
  • 30
  • I have to clear the background color of UIAlertController [UIColor clearColor] is not working any solution for this situation then please tell me – Yogesh Patel May 30 '19 at 12:56
1

This image shows an alert view structure enter image description here

If you want to change the background color you should change the 5th view's background color, for example, you can change it like this:

 alert.view.subviews.forEach { v in
        v.subviews.forEach { v in
            v.subviews.forEach { v in
                v.subviews.forEach { v in
                    v.backgroundColor = .black
                }
            }
        }
    }
Hamed
  • 1,678
  • 18
  • 30
0

In case someone wants to have an opaque white background color he can do this with this one liner:

UIVisualEffectView.appearance(whenContainedInInstancesOf: [UIAlertController.classForCoder() as! UIAppearanceContainer.Type]).backgroundColor = UIColor.white

Note however this will work properly only with white color as other colors will appear differently because of the default visual effect.

Leszek Szary
  • 9,763
  • 4
  • 55
  • 62
-1

let subview = (alert.view.subviews.first?.subviews.first?.subviews.first!)! as UIView subview.layer.cornerRadius = 1 subview.backgroundColor = UIColor.white

-1

If you want to use light and dark alert popup in your application, you can use this code, it works for me. Swift 5, Xcode 14.3

func testAlert(){
    let attributedString = NSAttributedString(string: "Title", attributes: [
        NSAttributedString.Key.font : UIFont.systemFont(ofSize: 18), //your font here
        NSAttributedString.Key.foregroundColor : UIColor.white
    ])

    let alert = UIAlertController(title: "", message: "",  preferredStyle: .alert)
    //Accessing alert view backgroundColor :
    alert.view.subviews.first?.subviews.first?.subviews.first?.backgroundColor = UIColor.black
    alert.setValue(attributedString, forKey: "attributedTitle")
    alert.view.tintColor = UIColor.white
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in
    }
    let okAction = UIAlertAction(title: "OK", style: .default) { (_) in
    }

    alert.addAction(cancelAction)
    alert.addAction(okAction)

    present(alert, animated: true, completion: nil)
}

enter image description here

akmoji
  • 79
  • 1
  • 2