Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Custom UIAlertController view

The docs say that subclassing UIAlertController is bad

The UIAlertController class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

So what is the recommended way to have an alert that shows not only a title, message and some buttons but also other stuff like ProgressBars, Lists, etc.?

In my special case I would like to have two different alerts, one that shows a ProgressBar and one that shows a list of error messages.

Currently I am trying to add the ProgressView manually and set constraints:

func getProgressAlert(onAbort: @escaping () -> ()) -> UIAlertController {
    let alert = UIAlertController(title: "Test", message: "Test", preferredStyle: .alert)

    let abort = UIAlertAction (title: "Abort", style: UIAlertActionStyle.cancel) { _ in
        onAbort()
    }
    alert.addAction(abort)

    let margin:CGFloat = 8.0
    let rect = CGRect(x:margin, y:72.0, width: alert.view.frame.width - margin * 2.0 , height:2.0)
    self.progressView = UIProgressView(frame: rect)
    self.progressView!.setProgress(0.0, animated: false)
    self.progressView!.tintColor = UIColor.blue
    alert.view.addSubview(self.progressView!)
    self.progressView!.translatesAutoresizingMaskIntoConstraints = false
    self.progressView!.widthAnchor.constraint(equalTo: alert.view.widthAnchor, multiplier: 1.0).isActive = true
    self.progressView!.heightAnchor.constraint(equalToConstant: 5.0).isActive = true
    self.progressView!.topAnchor.constraint(equalTo: alert.view.topAnchor).isActive = true
    self.progressView!.leftAnchor.constraint(equalTo: alert.view.leftAnchor).isActive = true       

    return alert
}

I don't think this is the way this should be done as manually defining constraints is very prone to errors on different devices. For example, the current code just shows the progress bar on the top of the alert view, but I want it to be shown between the message and the abort button.

like image 584
Simon Hessner Avatar asked Aug 21 '26 07:08

Simon Hessner


1 Answers

The view hierarchy for this class is private and must not be modified.

This is pretty much the nail in the coffin for this API. If you try hack it, you will cause yourself a lot of pain trying to support it across different iOS versions.

If want to have custom controls on an alert you will have to write a custom UIViewController subclass and mimic the API as best as you can whilst adding your new functionality (if you do not want to do this, there will be examples available on GitHub).

Some examples:

  • https://github.com/Codeido/PMAlertController
  • https://github.com/Orderella/PopupDialog
  • https://github.com/vikmeup/SCLAlertView-Swift
  • https://github.com/sberrevoets/SDCAlertView
like image 52
Oliver Atkinson Avatar answered Aug 23 '26 22:08

Oliver Atkinson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!