【问题标题】:Presenting UIAlertController (in actionsheet style) caused mysterious autolayout warning呈现 UIAlertController(以操作表样式)导致神秘的自动布局警告
【发布时间】:2020-06-24 02:42:26
【问题描述】:

这个问题可以通过一个简单的项目来重现,如下所示:

当用户单击导航栏上的+ 按钮时,代码会实例化并以操作表样式呈现UIAlertController

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)
    }
}

用户界面正确显示。问题是当操作表出现时 Xcode 会发出以下自动布局警告:

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.

当显示操作表时,我在 Xcode 中检查 UI 层次结构,发现一些子视图后跟一个感叹号:

我对此进行了谷歌搜索,但没有找到报告类似问题的人(即出现UIAlertController 时的自动布局警告)。我找到了一些关于如何在UIViewAlertForUnsatisfiableConstraints() 上设置断点以及如何调试汇编代码的信息。但我认为这是UIAlertController 的内部问题,我创建和呈现UIAlertController 的方式是常见且典型的。有什么建议我应该怎么做?

这可以在最新版本的 Xcode (11.3.1) 和 iOS (13.3) 上找到。如果我将样式更改为警报,问题就消失了。任何帮助将不胜感激。

【问题讨论】:

  • 我认为你无能为力,因为它的布局是由 iOS 完成的。约束即使在 SwiftUI 中也会发生这样的错误。
  • @Glenn 啊,非常感谢您提供的信息。这是我的第一个应用程序,我已经成功使用了很多其他 UI 控件和视图(我的意思是没有看到任何意外的自动布局警告),所以我认为这可能是我的错误。我浪费了整个上午的时间:(
  • 啊!一直在敲我的头!在我的应用程序中显示操作表时,我也遇到了这个奇怪的 -16 布局错误。没有任何作用,无法摆脱它。将动画设置为 false(见下文)也不起作用。我想我将不得不忍受它......

标签: ios autolayout uikit uialertcontroller


【解决方案1】:

这是 Apple 团队未修复的错误,此错误与动画相关的警报和操作表有关。您可以点击这些链接来验证这一点:-

UIAlertController's actionSheet gives constraint error on iOS 12.2 / 12.3

Swift default AlertViewController breaking constraints

解决方案是将动画值作为 false 传递:-

controller.present(alertController, animated: false, completion: nil)

我展示了没有动画的 UIAlertController,警告消失了。

或者你可以试试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

  }

【讨论】:

  • 谢谢!禁用动画对我不起作用(Xcode 11.3.1,iOS 13.3。我正在使用模拟器)。现在我知道这不是一个关键问题,我会避免尝试其他黑客,因为我还有更多其他事情要做:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多