Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift default AlertViewController breaking constraints

I am trying to use a default AlertViewController with style .actionSheet. For some reason, the alert causes a constraint error. As long as the alertController is not triggered (displayed) through a button, there are no constraint errors on the whole view. Could it be that this is a bug of Xcode?

The exact error I get looks like this:

2019-04-12 15:33:29.584076+0200 Appname[4688:39368] [LayoutConstraints] Unable to simultaneously satisfy constraints.     Probably at least one of the constraints in the following list is one you don't want.      Try this:          (1) look at each constraint and try to figure out which you don't expect;          (2) find the code that added the unwanted constraint or constraints and fix it.  (     "<NSLayoutConstraint:0x6000025a1e50 UIView:0x7f88fcf6ce60.width == - 16   (active)>" )  Will attempt to recover by breaking constraint  <NSLayoutConstraint:0x6000025a1e50 UIView:0x7f88fcf6ce60.width == - 16   (active)>  

This is the code I use:

@objc func changeProfileImageTapped(){         print("ChangeProfileImageButton tapped!")         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))         alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))         alert.view.tintColor = ColorCodes.logoPrimaryColor          self.present(alert, animated: true)     } 

As you can see, it is very basic. That's why I am very confused about the strange behavior I get as this default implementation should not cause any errors, right?

Output I get

Although, through breaking the constraints, the alert displays properly on all screen sizes I would be really thankful for any help I get.

like image 609
linus_hologram Avatar asked Apr 12 '19 13:04

linus_hologram


2 Answers

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() 
like image 93
jims1103 Avatar answered Sep 19 '22 08:09

jims1103


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) 
like image 43
Agisight Avatar answered Sep 20 '22 08:09

Agisight