【问题标题】:Strange UIView-Encapsulated-Layout-Height Error奇怪的 UIView-Encapsulated-Layout-Height 错误
【发布时间】:2015-04-09 05:23:04
【问题描述】:

我正在制作测试应用程序,所以在情节提要的 tableviewCell 中,我有 imageViewwebView(用于显示 html-text 的 webview)。

我为 imageView 设置了 top/left/right/height=200 等约束,它们之间的间距 =5 以及 webView 的 left/right/bot,所以我想要以编程方式计算我的 webView 高度,然后更改单元格的高度以拉伸我的 webView。但我明白了:

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 & fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property

    translatesAutoresizingMaskIntoConstraints) 
    (
        "<NSLayoutConstraint:0x7fd6f3773f90 V:[UIImageView:0x7fd6f3773e90(200)]>",
        "<NSLayoutConstraint:0x7fd6f3774280 UIImageView:0x7fd6f3773e90.top == UITableViewCellContentView:0x7fd6f3462710.topMargin>",
        "<NSLayoutConstraint:0x7fd6f3774320 V:[UIImageView:0x7fd6f3773e90]-(5)-[UIWebView:0x7fd6f3462800]>",
        "<NSLayoutConstraint:0x7fd6f3774370 UITableViewCellContentView:0x7fd6f3462710.bottomMargin == UIWebView:0x7fd6f3462800.bottom>",
        "<NSLayoutConstraint:0x7fd6f375ee40 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fd6f3462710(205)]>"
    )

有什么建议吗?

【问题讨论】:

  • 我在iOS8上得到了很多次,我仍然不明白这是否可能是iOS8的一种错误,因为在早期版本中没有引发异常。
  • 尝试更换到ios 7.0,但它仍然存在
  • 可能是因为 webview 是一个滚动视图被折叠到 0 高度并且当显示单元格时自动布局不能满足顶部和底部约束。尝试在 webview 中放置一个固定的高度,看看是否仍然显示警告
  • 我只想将“UIView-Encapsulated-Layout-Height”设置为单元格内容视图的高度(因为我自己在 IB 故事板中使用约束制作内容视图)。我认为设置 tableView.rowHeight = UITableViewAutomaticDimension 并将 tableView.estimatedRowHeight 设置为某个值会起作用(就像在 Ray Wenderlich 教程中所做的那样),但我无法理解!

标签: ios objective-c uitableview webview constraints


【解决方案1】:

UITextView 也有类似的问题。 尽管有人问过UIImageView 的问题,但许多人在遇到其他表格视图布局问题时会查看它。这个答案在任何情况下都适用,所以我决定分享它。

就我而言,提供的答案都没有帮助(尽管它们是正确的)。所以我想分享一个解决我问题的肮脏技巧。

  1. 确保您已将tableView.estimatedRowHeight 设置为某个值,并且tableView.rowHeight = UITableView.automaticDimension
  2. 确保单元格的子视图具有清晰的布局,可以在水平和垂直方向上限制它们(水平确定也很重要)。
  3. (HACK HERE)将属性添加到您的单元格var hack: (()-&gt; Void)?。 在你的cellForRowAtIndexPath 中设置为
cell.hack = { [weak self] in
    tableView.beginUpdates()
    tableView.endUpdates()
}

当你想调整它的大小时,从单元格调用这个块

【讨论】:

    【解决方案2】:

    我今天遇到了这个问题: - Xcode 11 - 使用 UITableViewAutomaticDimension - 使用估计行高度

    解决此问题的因素之一是在情节提要中将 tableView 的“Separator”属性设置为“None”。

    此外,如果您的约束导致小数高度(例如,如果您使用基于纵横比的乘数),则会导致与 UIView-Encapsulated-Layout-Height 冲突,后者始终被限制为整数值.解决方案是稍微降低高度约束的优先级。

    【讨论】:

    • 很高兴解释为什么 UIView-Encapsulated-Layout-Height 是 0.5 off。
    • 是的,tableView.separatorStyle = .none 修复了这个恼人的警告。
    【解决方案3】:

    以下代码对我不起作用

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
            return 100
        }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return UITableViewAutomaticDimension
        }
    

    不向一堆视图添加 translatesAutoresizingMaskIntoConstraints=false。

    最后,在数据源回调函数 tableView:cellForRowAt 中删除 cell.updateConstraintsIfNeeded() 会生成 Xcode 内容

    【讨论】:

    • 是的,我遇到了同样的问题。重用单元格时删除所有 setNeedsLayout 和 layoutIfNeeded 调用。
    【解决方案4】:

    到目前为止,我已经看到了两个发生这种情况的案例。一个记录在接受的答案中,即您的 tableView:heightForRow: 实现必须返回您的约束将计算到的相同值。

    另一种情况是如果您忘记在一个或多个自动布局视图上设置 translatesAutoresizingMaskIntoConstraints = NO(或 Swift 为 false)。在向以编程方式创建的视图添加约束之前,请关闭自动调整大小,如下所示:

    view.translatesAutoresizingMaskIntoConstraints = false
    

    否则,如果您的视图具有由自动调整掩码指定的固定宽度或高度,则将创建一个约束来强制执行它。

    【讨论】:

      【解决方案5】:

      我今天遇到了这个问题。我在屏幕上有一个集合视图,但这不是问题。我正在使用自定义容器视图控制器,并且在容器视图本身布局之前布局了一些视图。 诀窍是通过在容器视图控制器上调用 loadViewIfNeeded() 来确保首先布局容器视图。

      这意味着如果原始问题中的0x7fd6f375ee40 是来自视图控制器的视图,则您可能需要在布局某些子视图之前检查是否正在加载该视图层次结构。

      【讨论】:

        【解决方案6】:

        我试图实现一个简单的单元格,其顶部有一行标签,底部有一个 n 行标签,可以随着更长的文本展开,希望单元格会根据我的约束自动扩展以适应内容。

        对我来说很有趣,解决这个问题的方法是覆盖 - tableView:heightForRowAtIndexPath:tableView:estimatedHeightForRowAtIndexPath: 并返回我的估计行高和 UITableViewCellAutomaticDimension,而不是在我的 tableView 上设置 rowHeightestimatedRowHeight @987654326 @。

        【讨论】:

          【解决方案7】:

          对不起,我迟到了。 :)

          如果首先需要约束,则降低 Autolayout 试图打破的约束的优先级可能不是解决方案。

          前几天我遇到了这个问题,这是我的布局:

          • OuterView C1:宽度约束等于它的父视图
            • StackView
            • ChildView C3:固定宽度约束,常量 = StackView.frame.size.width

          问题发生在我减小 C1 的宽度时,很明显因为 C3 处于固定宽度,取原始帧大小,减小 C1 导致冲突,并且 C1 被 iOS 破坏以修复问题。

          通过将 C3 设置为采用 StackView 的 widthAnchor 而不是其帧大小,问题很快得到解决。

          错误的约束

          view.widthAnchor.constraint(equalToConstant: stackView.frame.size.width).isActive = true

          右约束

          view.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 1.0).isActive = true

          这样,每当 C1 发生变化时,所有子约束都会对其做出相应反应。

          结论:

          1. 我不认为这个错误是某些人所说的错误。
          2. 通过调整优先级解决问题,但这是您想要的预期结果吗?
          3. 如果您决定不优先解决它,请查看您的约束,尤其是那些以编程方式设置的约束,以检查是否存在冲突。如果您正在处理视图(例如单元格视图)的动态宽度或高度,请确保父视图的高度或宽度约束与这些动态更改不冲突,并继续向上工作。

          【讨论】:

            【解决方案8】:

            如果您使用tableView.rowHeight = UITableViewAutomaticDimension,则应始终设置estimatedRowHeight。例如:

            tableView.estimatedRowHeight = 44
            

            或者你应该实现:

            func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
            

            否则您将始终收到警告UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView,并且内容将以错误的方式折叠

            【讨论】:

            • 提醒其他阅读本文的人。如果您使用页眉和/或页脚,还有 .estimatedSectionHeaderHeight 和 .estimatedSectionFooterHeight 属性。
            • 仅供参考 - 我已经看到在表格视图上设置估计的行高与实现该功能的差异。该功能有效,setter 在我的情况下似乎没有。
            【解决方案9】:

            对于我来说,我使用估计的单元格高度,为了解决这个问题,我将约束的优先级从标签底部到它的邻居设置为 999,它起作用了。

            【讨论】:

              【解决方案10】:

              这个错误发生在我身上,UIButton 试图通过创建与我的顶部和底部约束冲突的 UIView-Encapsulated-Layout-Height 来自动调整其高度。

              我通过显式添加高度约束来修复它。

              【讨论】:

                【解决方案11】:

                我通常通过降低AutoLayout 试图打破的约束的优先级来消除此警告。所以如果它说:

                Will attempt to recover by breaking constraint 
                <NSLayoutConstraint:0x7fd7c2ecb520 V:[UIView:0x7fd7c2ecd0e0(300)]>
                

                继续并将其优先级降低到999

                应该可以。

                干杯。

                【讨论】:

                • 它有效,但真正的原因是什么?
                • @PhineasLue 在我的情况下,我将约束(a)作为默认约束,然后我更新并添加另一个约束(b)以某种方式达到约束 a 现在您需要在 ab 将出现在您的视图中的最终约束,如果您选择 a 您需要将 b 的优先级设置为 999 就像说让位给约束 a
                • 谢谢!愚蠢的是,这是必要的,但我很高兴摆脱虚假警告。
                • 它有效。结果显示警告Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.你们遇到这种情况了吗?
                • 此解决方案适用于 Xcode 版本 7.3.1 (7D1014)。我注意到的是,在我的情况下,在 IB 中,131 px 的 UITableViewCell 高度使 IB 自动布局引擎感到高兴,但 contentView 在 IB 中显示为 130 px,这是不正确且不可更改的。我认为这是 Xcode IB 自动布局引擎和 iOS 运行时自动布局之间的错误。
                猜你喜欢
                • 1970-01-01
                • 2017-02-01
                • 2015-10-09
                • 2016-03-04
                • 1970-01-01
                • 2021-05-21
                • 2021-09-01
                • 2015-01-13
                • 2015-11-18
                相关资源
                最近更新 更多