Swift default AlertViewController breaking constraints

Adding to this answer...This seems to remove the issue for me and doesn't require any changes to existing code.

extension UIAlertController {
    override open func viewDidLoad() {
        super.viewDidLoad()
        pruneNegativeWidthConstraints()
    }

    func pruneNegativeWidthConstraints() {
        for subView in self.view.subviews {
            for constraint in subView.constraints where constraint.debugDescription.contains("width == - 16") {
                subView.removeConstraint(constraint)
            }
        }
    }
}

The following removes the warning without needing to disable animation. And assuming Apple eventually fixes the root cause of the warning, it shouldn't break anything else.

extension UIAlertController {
    func pruneNegativeWidthConstraints() {
        for subView in self.view.subviews {
            for constraint in subView.constraints where constraint.debugDescription.contains("width == - 16") {
                subView.removeConstraint(constraint)
            }
        }
    }
}

This can then be used like this:

// After all addActions(...), just before calling present(...)
alertController.pruneNegativeWidthConstraints()

It's a new bug in iOS versions:

  • 12.2
  • 12.3
  • 12.4
  • 13.0
  • 13.1
  • 13.2
  • 13.2.3
  • 13.3
  • 13.4
  • 13.4.1
  • 13.5
  • 13.6
  • 14.0
  • 14.2
  • 14.4

The only thing we can do is to file a bug report to Apple (I just did that and you should too).

I'll try to update answer for a new version(s) of iOS when it come out.


This error is not critical, seems to be unfixed bug form Apple. This constraint appears in animation style just after presenting. enter image description here I tried to catch and change it (change values, relations, priority) before presenting – no success because of this dynamically added constraints.

When you turn off animation in self.present(alert, animated: false) and using alert.view.addSubview(UIView()) – the error disappears. I can't explain it, but it works!

let alert = UIAlertController(title: "Change your profile image", message: nil, preferredStyle: .actionSheet)

alert.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Online Stock Library", style: .default, handler: nil))
let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)

alert.addAction(cancel)
alert.view.addSubview(UIView()) // I can't explain it, but it works!

self.present(alert, animated: false)