2

The issue can be reproduced with a simple project as below:

enter image description here

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:

enter image description here

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.

rayx
  • 1,329
  • 10
  • 23
  • 3
    I reckon there's nothing you can do about it, since given that its layout is done by iOS. Constraints errors like that happen even in SwiftUI. – Glenn Posadas Mar 12 '20 at 04:10
  • @Glenn Ah, thanks much for the information. This is my first App and I have used quite a few other UI controls and views successfully (I mean not seeing any unexpected autolayout warnnings), so I thought it might be my mistake. I wasted the entire morning on this :( – rayx Mar 12 '20 at 04:16
  • Ah! Been banging my head on this! I too get this strange -16 layout error on presenting actionsheets in my app. Nothing works, can' get rid of it. Setting animation to false (see below) doesn't work either. Guess I'll have to live with it ... – DeveloperSammy Nov 17 '20 at 13:01

1 Answers1

3

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

  }
Apps Maven
  • 1,314
  • 1
  • 4
  • 17
  • Thanks! Disabling animation doesn't work for me (Xcode 11.3.1, iOS 13.3. I'm using simutlator). Now that I know it's not a critical issue, I'll refraim from trying other hacks because I have more other things to do :) – rayx Mar 12 '20 at 06:27