The issue can be reproduced with a simple project as below:
When user clicks the +
button on the navigation bar, the code instantiates and presents an UIAlertController
in actionsheet style.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func buttonTapped(_ sender: Any) {
let actionSheet = UIAlertController(title: nil,
message: nil,
preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Create Income",
style: .default) { _ in
print("Income!") })
actionSheet.addAction(UIAlertAction(title: "Create Outcome",
style: .default) { _ in
print("Outcome!")})
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in })
self.present(actionSheet, animated: true, completion: nil)
}
}
The UI shows up correctly. The issue is Xcode emits the following autolayout warnings when the action sheet appears:
2020-03-12 11:24:57.002113+0800 alertcontroler_test[12757:936231] [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:0x600002d11b30 UIView:0x7f851961c560.width == - 16 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600002d11b30 UIView:0x7f851961c560.width == - 16 (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
I check UI hierarchy in Xcode when the action sheet is showing up and find some subviews are followed by a exclamation mark:
I google about this but don't find people reporting similar issue (that is, autolayout warnings when UIAlertController
shows up). I find some information about how to set break point on UIViewAlertForUnsatisfiableConstraints()
and how to debug assemble code. But I think this is an internal issue in UIAlertController
and the way how I create and present UIAlertController
is common and typical. Any suggestion what I should do?
This is found on latest version of Xcode (11.3.1) and iOS (13.3). The issue is gone if I change style to alert. Any help would be greatly appreciated.
This is a bug which is not fixed by Apple team this bug is related to alerts and action sheets related to animation. You may follow these links to verify this:-
UIAlertController's actionSheet gives constraint error on iOS 12.2 / 12.3
Swift default AlertViewController breaking constraints
The solution for this is to pass animation value as false like:-
controller.present(alertController, animated: false, completion: nil)
I have present the UIAlertController without animation and warning got vanished.
or you may try this solution mentioned in the one of the links of stackoverflow:-
@IBAction func buttonTapped(_ sender: UIButton) {
...
self.present(alertController,animated: true,completion: nil)
alertController.view.subviews.flatMap({$0.constraints}).filter{ (one: NSLayoutConstraint)-> (Bool) in
return (one.constant < 0) && (one.secondItem == nil) && (one.firstAttribute == .width)
}.first?.isActive = false
}