【问题标题】:Autolayout warning when using prompt in navigation bar在导航栏中使用提示时自动布局警告
【发布时间】:2019-07-20 13:26:00
【问题描述】:

我正在使用带有提示的导航栏,如下所示:

我在控制台中收到以下自动布局警告:

2019-09-01 21:26:03.225576+0200 Hortus[85622:2386450] [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:0x600002d16990 UILabel:0x7fc9eb816f50'Testen'.centerX == _UINavigationBarModernPromptView:0x7fc9ebe27780.centerX   (active)>",
    "<NSLayoutConstraint:0x600002d15c20 UILabel:0x7fc9eb816f50'Testen'.leading >= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.leading   (active)>",
    "<NSLayoutConstraint:0x600002d10ff0 '_UITemporaryLayoutWidth' _UINavigationBarModernPromptView:0x7fc9ebe27780.width == 0   (active)>",
    "<NSLayoutConstraint:0x600002d16a30 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'](LTR)   (active, names: '|':_UINavigationBarModernPromptView:0x7fc9ebe27780 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600002d15c20 UILabel:0x7fc9eb816f50'Testen'.leading >= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.leading   (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.

2019-09-01 21:26:03.226198+0200 Hortus[85622:2386450] [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:0x600002d16990 UILabel:0x7fc9eb816f50'Testen'.centerX == _UINavigationBarModernPromptView:0x7fc9ebe27780.centerX   (active)>",
    "<NSLayoutConstraint:0x600002d15540 UILabel:0x7fc9eb816f50'Testen'.trailing <= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.trailing   (active)>",
    "<NSLayoutConstraint:0x600002d10ff0 '_UITemporaryLayoutWidth' _UINavigationBarModernPromptView:0x7fc9ebe27780.width == 0   (active)>",
    "<NSLayoutConstraint:0x600002d14320 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide']-(8)-|(LTR)   (active, names: '|':_UINavigationBarModernPromptView:0x7fc9ebe27780 )>"

    "<NSAutoresizingMaskLayoutConstraint:0x60000043be30 h=--& v=--& _UINavigationBarModernPromptView:0x7fb3c6416640.width == 0   (active)>",
    "<NSLayoutConstraint:0x600000421400 UILabel:0x7fb3c66d8bf0'Plant guide'.centerX == _UINavigationBarModernPromptView:0x7fb3c6416640.centerX   (active)>",
    "<NSLayoutConstraint:0x600000421f90 UILabel:0x7fb3c66d8bf0'Plant guide'.trailing <= UILayoutGuide:0x600001e58fc0'UIViewLayoutMarginsGuide'.trailing   (active)>",
    "<NSLayoutConstraint:0x600000421e00 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600001e58fc0'UIViewLayoutMarginsGuide']-(20)-|(LTR)   (active, names: '|':_UINavigationBarModernPromptView:0x7fb3c6416640 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600002d15540 UILabel:0x7fc9eb816f50'Testen'.trailing <= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.trailing   (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.

这些警告是针对导航栏中的提示给出的,但我没有为导航栏设置自动布局约束。这应该由IOS自己处理。

如何解决这些警告?

[编辑] 当连接到视图控制器时,prepare() 中会给出警告。我在prepare() 中设置了提示。 segue 是一个故事板参考,并被定义为“模态呈现”。故事板参考引用了 UINavigationController。提示设置在导航控制器的根视图控制器上。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let identifier = segue.identifier {
        switch identifier {

        case "editImage":
            let nc = segue.destination as? TTImageNavigationController
            if let rvc = nc?.rootViewController as? TTImageEditorController {
                rvc.navigationItem.prompt = navigationItem.prompt
            }

        default:
            break
        }
    }
}

[编辑] 似乎大多数反应的人都不清楚这个问题。再次......我没有在代码或情节提要中设置任何自动布局设置。在 segue 之前的 prepare() 函数中设置提示后,导航栏出现问题。上面给出了代码。任何说我必须更改或检查我的约束的反应都没有帮助,因为没有要检查的约束!

[编辑] 应 Mohsen 的要求,我在 github 上创建了一个小示例项目:https://bitbucket.org/Leontien/navigationbarautolayoutwarning/src/master/

【问题讨论】:

  • 您能否提供更多代码,因为这在很多情况下都会出现?
  • 我不确定您希望看到哪些额外的代码。在代码中,我只设置了提示:viewController.navigationItem.prompt = "Plant guide"。导航栏添加到情节提要中并且不包含提示,因为提示是通过编程设置的。
  • @Leontien 您的日志只是列表约束,不包含任何警告,请添加更多日志。我没有出现在我的机器上。
  • @Thanh,我在问题中添加了完整的近期警告记录
  • 什么版本的 Xcode / iOS?

标签: ios swift autolayout uinavigationbar


【解决方案1】:

这不是你的错误。这是苹果的错误。忽略控制台。向 Apple 提交报告并继续前进。

【讨论】:

    【解决方案2】:

    为您的约束设置优先级。这将根据优先级满足约束。请参考this链接。

    【讨论】:

    • 我不知道如何才能清楚地表明我没有任何限制!警告是针对导航栏的,我没有为导航栏设置任何自动布局约束。
    • 请检查您在导航栏中放置的图像大小,您可以将图像放在 Assets.xcassets 中。还要检查导航栏的标题标签。
    • 图片大小?正如您在描述中的代码中看到的那样,我没有在导航栏中放置图像。我只给导航栏的提示设置了一个字符串。
    【解决方案3】:

    您为标签设置 centerX 并为左右按钮设置前导和尾随,您也没有为 UILabel 设置任何宽度限制

     "<NSLayoutConstraint:0x600002d16990 UILabel:0x7fc9eb816f50'Testen'.centerX == _UINavigationBarModernPromptView:0x7fc9ebe27780.centerX   (active)>",
    "<NSLayoutConstraint:0x600002d15c20 UILabel:0x7fc9eb816f50'Testen'.leading >= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.leading   (active)>",
    "<NSLayoutConstraint:0x600002d10ff0 '_UITemporaryLayoutWidth' _UINavigationBarModernPromptView:0x7fc9ebe27780.width == 0   (active)>",
    "<NSLayoutConstraint:0x600002d16a30 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'](LTR)   (active, names: '|':_UINavigationBarModernPromptView:0x7fc9ebe27780 )>"
    

    "<NSLayoutConstraint:0x600002d16990 UILabel:0x7fc9eb816f50'Testen'.centerX == _UINavigationBarModernPromptView:0x7fc9ebe27780.centerX   (active)>",
        "<NSLayoutConstraint:0x600002d15540 UILabel:0x7fc9eb816f50'Testen'.trailing <= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.trailing   (active)>",
        "<NSLayoutConstraint:0x600002d10ff0 '_UITemporaryLayoutWidth' _UINavigationBarModernPromptView:0x7fc9ebe27780.width == 0   (active)>",
        "<NSLayoutConstraint:0x600002d14320 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide']-(8)-|(LTR)   (active, names: '|':_UINavigationBarModernPromptView:0x7fc9ebe27780 )>"
    
        "<NSAutoresizingMaskLayoutConstraint:0x60000043be30 h=--& v=--& _UINavigationBarModernPromptView:0x7fb3c6416640.width == 0   (active)>",
        "<NSLayoutConstraint:0x600000421400 UILabel:0x7fb3c66d8bf0'Plant guide'.centerX == _UINavigationBarModernPromptView:0x7fb3c6416640.centerX   (active)>",
        "<NSLayoutConstraint:0x600000421f90 UILabel:0x7fb3c66d8bf0'Plant guide'.trailing <= UILayoutGuide:0x600001e58fc0'UIViewLayoutMarginsGuide'.trailing   (active)>",
        "<NSLayoutConstraint:0x600000421e00 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600001e58fc0'UIViewLayoutMarginsGuide']-(20)-|(LTR)   (active, names: '|':_UINavigationBarModernPromptView:0x7fb3c6416640 )>"
    

    为了解决这个警告,你应该从 UILabel 中删除前导和尾随约束,并将左按钮设置为超视图,右按钮也设置为超视图。

    或者你可以使用导航栏对象,它有一个标签,你也可以给它添加 barButtonItem。

    您可以为 UILabel 添加宽度限制,但是当您在其他设备上运行它时,它会在其他设备上发生冲突

    【讨论】:

    • 你开始说我设置了一些约束,没有设置其他约束....我根本没有设置任何约束!这是我使用的默认导航栏,我只设置标题和提示的字符串。
    • 默认导航栏有uilabel,不需要添加UILabel
    • 为什么你认为我添加了 UILabel?我使用默认标签作为标题和提示。
    • @Leontien 您可以将警告样本推送到 git 存储库吗?
    • 我编辑了我的描述并在 GitHub 中添加了一个示例项目的链接。
    【解决方案4】:

    这有助于通过提供更具可读性的输出来调试损坏的约束问题

    • 为 NSLayoutConstraint 创建一个扩展
    
    extension NSLayoutConstraint {
        override open var description: String {
            let id = identifier ?? ""
            return "Constraint ID: \(id), constant: \(constant)"
        }
    }
    
    • 为情节提要中的每个约束设置唯一标识符

    • 你会得到一个更易读的输出,指出哪个约束 id 被破坏了

    • 更改破坏约束的优先级

    【讨论】:

    • 请重新阅读我的描述的最后一部分:我没有任何要更改的限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    相关资源
    最近更新 更多