检测到约束模糊地表明高度为零的情况

Posted

技术标签:

【中文标题】检测到约束模糊地表明高度为零的情况【英文标题】:Detected a case where constraints ambiguously suggest a height of zero 【发布时间】:2014-11-12 04:21:17 【问题描述】:

当我运行包含 tableview 单元格的应用程序更新到 Xcode 6.1 beta 2 后,调试助手说:

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 5 时,我会遇到一些错误,但这些错误在我升级后就消失了。我现在没有其他错误或警告。我已经尝试过调整所有 tableview 单元格的大小并尝试使用标准高度,但我仍然收到相同的警告:

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.

我也通读了所有类似的主题,但他们的解决方案都没有帮助。当我用模拟器测试应用程序时,应用程序运行良好,只是应该在 tableView 单元格中的图片不存在。

【问题讨论】:

我在集合视图单元格中遇到同样的错误。我为此做什么。任何建议。 也许你应该检查你是否已经将xib文件添加到目标***.com/a/26870331/1418457 ios8 - constraints ambiguously suggest a height of zero的可能重复 这发生在我的 iOS 8.1 上,但不再发生在 iOS 8.4 上。如果您确实指定了高度,我想这只是一个 Xcode 错误。 【参考方案1】:

您会遇到 iOS8 的 Tableviews 中一项奇妙的新功能的副作用:自动行高。

在 iOS 7 中,您要么拥有固定大小的行(使用 tableView.rowHeight 设置),要么编写代码来计算单元格的高度,然后将其返回到 tableView:heightForRowAtIndexPath。如果单元格中有许多视图并且在不同的字体大小下需要考虑不同的高度,则编写用于计算单元格高度的代码可能会非常复杂。添加动态类型,这个过程很痛苦。

在 iOS 8 中,您仍然可以执行上述操作,但现在行的高度可以由 iOS 确定,前提是您已使用自动布局配置了单元格的内容。这对开发人员来说是巨大的好处,因为随着动态字体大小的变化,或者用户使用辅助功能设置修改文本大小,您的 UI 可以适应新的大小。这也意味着如果您有一个可以包含多行文本的 UILabel,您的单元格现在可以在单元格需要时增长以适应那些,并在不需要时缩小,因此没有任何不必要的空白。

您看到的警告消息是告诉您单元格中没有足够的约束用于自动布局来通知表格视图单元格的高度。

要使用动态单元格高度,以及其他海报已经提到的技术,也将消除此消息,您需要确保您的单元格有足够的约束来将 UI 项目绑定到顶部 并且单元格的底部。如果您之前使用过 Auto Layout,您可能习惯于设置 Top + Leading 约束,但动态行高也需要底部约束。

布局过程是这样工作的,它在单元格显示在屏幕上之前立即以即时方式发生:

    计算具有固有尺寸的内容的尺寸。这包括 UILabels 和 UIImageViews,它们的尺寸分别基于它们包含的文本或 UIImages。这两个视图都会认为它们的宽度是已知的(因为您已经为后缘/前缘设置了约束,或者您设置了明确的宽度,或者您使用了最终显示从一侧到另一侧的宽度的水平约束)。假设一个标签有一段文本(“行数”设置为 0,所以它会自动换行),它只能是 310 磅,所以在当前字体大小下它被确定为 120pt 高。

    UI 根据您的定位约束进行布局。标签底部有一个约束连接到单元格的底部边缘。由于标签已经增长到 120 点高,并且由于它被约束绑定到单元格的底部,它必须将单元格“向下”(增加单元格的高度)以满足“底部标签始终是距单元格底部的标准距离。

如果缺少底部约束,则会出现您报告的错误消息,在这种情况下,没有任何东西可以将单元格的底部“推”离单元格的顶部,这是报告的歧义:没有什么可以推动从上往下,细胞塌陷。但自动布局也检测到这一点,并回退到使用标准行高。

对于它的价值,并且主要是为了得到一个全面的答案,如果你确实实现了 iOS 8 的基于自动布局的动态行高,你应该实现tableView:estimatedHeightForRowAtIndexPath:。该估计方法可以为您的单元格使用粗略的值,并且会在最初加载表格视图时调用。它帮助 UIKit 绘制滚动条之类的东西,除非 tableview 知道它可以滚动多少内容,否则无法绘制滚动条,但不需要完全准确的大小,因为它只是一个滚动条。这使得实际行高的计算被推迟到需要单元格的那一刻,这减少了计算密集度,并且让你的 UITableView 呈现得更快。

【讨论】:

这是对这个警告根本原因的一个很好的解释。非常感谢您,伍德斯特! 就像 Woodster 所说的那样,我确实错过了约束的 .Bottom 部分。添加后,我的问题得到了解决。 在尝试了近 20 种方法之后,这是唯一有效的方法! 这个人成功了!他应该得到支持和支持,这必须是公认的答案。 +1 查看此答案***.com/a/29565073/4080860 以确定哪些单元格缺少约束。【参考方案2】:

到目前为止,三件事已经成功地消除了这个警告。您可以选择最方便的。不过没什么好看的。

在 viewDidLoad 中设置默认单元格的高度

self.tableView.rowHeight = 44;

转到情节提要并将 tableview 上的行高更改为不同于 44 的值。

实现tableview的委托方法heightForRowAtIndexPath

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

    return 44;

很奇怪。

【讨论】:

我也尝试过使用您的方法,但我需要为 rowHeight 添加一个@property,但我不知道要使用的正确对象类型 我可能没听明白,但是 rowHeight 是 UITableView 的一个属性。只需将您的桌子连接到某个插座即可。 这是因为如果您将 44pt 值保留在 IB 中,它将考虑您要使用自调整大小的单元格。 ***.com/questions/25888126/…(但是,是的,这确实是一种奇怪的行为) 所以显然我有两个 viewDidLoad 方法,我把 self.tableView.rowHeight = 44; 放在了错误的一个中。错误消失了!谢谢 感谢 Guillaume Algis 让这一点更清楚。不过,它仍然非常令人毛骨悚然。【参考方案3】:

要在没有编程方法的情况下解决此问题,请在情节提要的 Size Inspector 中调整表格视图的行高。

【讨论】:

对我来说最好的解决方案,因为使用情节提要的东西而不是代码行。【参考方案4】:

在创建自定义 UITableViewCell 并将我的子视图添加到单元格而不是其 contentView 后,我遇到了这个问题。

【讨论】:

【参考方案5】:

这是一个自动布局问题。确保您的子视图具有所有约束。对我来说,单元格中的标题标签缺少底部约束。当我添加它时,警告消失了,一切都完美地显示出来。

【讨论】:

不知道为什么这被否决了,因为这是一个非常好的答案。有关确定哪个单元格的布局有问题的帮助,请参见此处***.com/a/29565073/4080860【参考方案6】:

只需启用 Self-Sizing Table View Cells

   tableView.estimatedRowHeight = 85.0
   tableView.rowHeight = UITableViewAutomaticDimension

& 确保您在UITableViewCell as-的所有方面都添加了约束-

Example Link 1

Example Link 2

【讨论】:

实际上,当我禁用 self-sizig tableview单元格时,警告就消失了。 @turingtested 你应该启用自我调整大小的表格视图单元格,以便在各种设备上提供支持。 同意,但请阅读原始问题。我的意思是您建议的解决方案不起作用,至少对我不起作用。 仅供参考 UITableViewAutomaticDimension 已重命名为 UITableView.automaticDimension【参考方案7】:

如果您使用静态单元格或动态单元格,只需在检查器表中的表格视图中添加一些行高并取消选中行高右侧的自动,您将停止收到此警告。

【讨论】:

我发现相反的方法更有效:设置一个明确的估计高度,并让行高本身是自动的。【参考方案8】:

我今天收到了这个警告。这就是让我消失的原因(在界面生成器中)

1.将表格视图的行高字段设置为 44 以外的值 2 将 tableView 单元格的行高字段设置为 44 以外的值

我不必对代码进行任何更改

【讨论】:

【参考方案9】:

就我而言,我正在以编程方式构建单元并不断收到此错误。

我在UITableViewCellinit 方法中添加了子视图和约束,如下所示:

addSubview(rankingLabel)
addConstraints(cellConstraints)

我通过将它们添加到单元格的contentView 解决了这个问题:

contentView.addSubview(rankingLabel)
contentView.addConstraints(cellConstraints)

【讨论】:

总是将子视图添加到contentView,而不是直接添加到UITableViewCell【参考方案10】:

将估计的行高设置为零,警告消失:

【讨论】:

真正的问题是某处缺少约束。您可能正在垂直输入某些内容,而不是设置顶部/底部约束【参考方案11】:

如果您为 tableView 创建了自定义 tableViewCell,请确保您已为单元格提供底部和顶部约束, 如果您的自定义单元格内的子视图在 Y 中心对齐,您也可能会收到此消息,这不会弹出任何错误消息,但会依次识别 tableview 的行高like in Image I have attached , here we have both top and bottom constraints

当您为 tableView 创建自定义单元格时,您必须为单元格内自定义单元格的子视图指定行高或顶部和底部约束(例如,自定义单元格中的标签,如下图所示)

但如果这不起作用,您可以尝试为您的单元格设置行高,而不是自动设置like in this image

但请确保如果您关闭自动勾选,则必须以编程方式调整行大小以进行本可以自动完成的更改

【讨论】:

【参考方案12】:

我今天收到了这个警告我所做的只是在我的代码中多加了一行

tableView.rowHeight = 200;

在里面添加这行代码

func tableView(_ tableView: UITableView, numberOfRowsInSection section:Int) -> Int 
  ...

最终代码看起来像

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
  tableView.rowHeight = 200;
  ...

此代码会将表格行单元格高度增加到 200,默认高度为 44

【讨论】:

【参考方案13】:

在迁移到 Xcode 6 GM 时,我也遇到了这个警告。当我将设备旋转回原来的位置时,我才收到警告。

我正在使用自定义 UITableViewCells。故事板表格视图设置为我的自定义大小(在我的情况下为 100.0)。虽然表格单元格像以前的版本一样正确呈现,但我不喜欢警告消息。

除了上面的想法,我加了这个

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    return 100.0;

屏幕呈现...响应旋转并且没有更多警告消息。

【讨论】:

所以我已经尝试使用你给我的线路使用你的方法,但我仍然想出了同样的错误。我也没有在我的应用程序中使用轮换。【参考方案14】:

在 xcode 6.0.1 中,我已删除此警告,指定行高使用:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    return 44.0;

【讨论】:

【参考方案15】:

对于具有动态行高的自定义表格视图单元格,我也有类似的问题。动态高度未反映并在控制台中得到相同的警告。解决方案是将子视图添加到单元格而不是 contentView。顺便说一句,我以编程方式创建了子视图。

【讨论】:

【参考方案16】:

我在TableViewCells 上遇到了这个问题,其中在初始化时设置了约束,但之后加载了单元格的内容,这意味着自动布局引擎无法确定高度。这里的其他解决方案不起作用,因为我需要单元格的高度为 UITableView.automaticDimension

我刚刚为单元格添加了一个额外的约束:

contentView.heightAnchor.constraint(equalToConstant: 44, priority: .defaultLow)

【讨论】:

这对我有用。而不是使用 .defaultLow,我需要使用 .defaultHigh【参考方案17】:

在情节提要中,将cell Row height 字段设置为与tableView 中的Row height 相同的值(对我来说都具有相同的值)。

如果将heightForRowAtIndexPath 函数添加到代码中,可能会导致性能问题,因为它会为每个单元格调用,所以要小心。

【讨论】:

【参考方案18】:

如果您的唯一约束设置为垂直对齐所有项目并且您没有/不希望为单元格指定高度,您也可能会看到此消息。如果您在项目上设置了顶部/底部约束,则警告将消失。

【讨论】:

【参考方案19】:

当我在自定义 tableViewCell 中的标签和视图被限制到 customCell 而不是它的内容视图时,我遇到了这个问题。当我清除约束并将它们连接到单元格内容视图时,问题就解决了。

【讨论】:

【参考方案20】:

我有同样的错误信息, 确保所有的 outlet 都是有效的,比如 table view 和 tableview 约束

【讨论】:

【参考方案21】:

如果要进行动态高度计算,

您应该将所有元素根据顶部和底部等约束条件相互链接。 您绝对应该有一个 bottom 约束,该约束链接到单元格底部的元素

【讨论】:

【参考方案22】:

如果您使用 UITableView 扩展 ViewController 类并使用导航控制器显示屏幕,那么您不需要使用标识符执行 segue 这可能会导致标识符 ViewController 错误,您可以使用 pushViewController 方法显示聊天屏幕为了摆脱这个错误所以这里的代码只是将它粘贴到你的 UItableView 委托

让 chatBox = ChatBoxViewController() navigationController?.pushViewController(chatBox, animated: true)

只需输入您要在接下来显示的视图控制器的名称即可。

【讨论】:

【参考方案23】:

我有同样的错误,由于这一行显示了这个错误。

self.layer.backgroundColor = UIColor(white: 1, alpha: 0.2) as! CG颜色

我只是更改以下行来修复错误

self.layer.backgroundColor = UIColor(white: 1, alpha: 0.2).cgColor

【讨论】:

以上是关于检测到约束模糊地表明高度为零的情况的主要内容,如果未能解决你的问题,请参考以下文章

VoiceOver 是不是总是忽略宽度和高度为零的 iOS 视图?

在自动布局的情况下,IOS scrollview 模糊的可滚动内容高度

使自定义单元格(使用自动布局创建)高度为零

AutoLayout 将 UILabel 高度设置为零

在不知道文件描述符的情况下检测文件大小不为零的最快方法是啥?

浮动清除