iOS8-约束模糊地建议高度为零


100

有人知道如何调试吗?

仅警告一次:检测到一种情况,即约束条件模糊地表明表格视图单元格的内容视图的高度为零。我们考虑的是无意倒塌,而是改用标准高度。

行的固定高度由

- (CGFloat)tableView:(UITableView *)tableView 
           heightForRowAtIndexPath:(NSIndexPath *)indexPath{
   return 34.0;
}

一切constraints似乎都很幸福...

Answers:


129

强迫返回高度和估计高度使警告消失了。

- (CGFloat)tableView:(UITableView *)tableView 
           estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44;
}

- (CGFloat)tableView:(UITableView *)tableView 
           heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44;
}

不需要这两个替代的另一个解决方案是仅self.tableView.rowHeight = 44;在您的loadViewinit方法中使用。


1
我在节中有多个类型行,并且其中只有一个具有动态高度。那么它就不起作用
Raj Aggrawal

如果我们在xib / storyboard中设置默认高度,则不必实现这些方法。
萨蒂扬

77

还可以做的是在内容视图的顶部和底部添加垂直约束。这将使自动布局开心(因为他现在知道如何自己计算单元的高度)。


2
这对我有用。我遍历了所有容器单元,并确保至少一个子视图同时具有“容器顶部空间”和“容器底部空间”约束。
Rog182

7
使用自定义表格视图单元格时,这是iOS 8的正确答案。
tsafrir 2015年

1
您是指从内容视图内部的元素到内容视图顶部和底部的约束吗?
扎克·夏皮罗

我尝试了这个,但是我不断收到冲突的约束警告。
Shirish Kumar 2015年

2
确保将顶部和底部约束添加到单元的内容视图,而不是单元本身。如果添加约束到小区,该代码仍然工作,但会尝试使用的0高度
frin

26

如果您使用的是autoLayout约束和UITableViewAutomaticDimension,则此错误不是通过覆盖代码中的高度而被丢弃的一些错误问题。这意味着无法自动确定像元高度,因为您没有适当的垂直约束。

如果您像我一样遇到此错误,并且需要帮助来确定哪个单元引发了该错误,则可以在返回“ heightforRowAtIndexPath”方法之前添加以下行。

NSLog(@"Section %ld Row %ld", (long)[indexPath section], (long)[indexPath row]);

这将打印出一长串的节和行,但是该错误将立即出现在导致该错误的特定单元格之后,并且您可以快速识别出哪个单元格导致了该问题并相应地解决约束。这对于静态单元格特别有用。如果您不使用autoLayout和自动单元格高度,则使用手动输入的数字替代高度是可行的,但是实际上将禁用这些功能,如果您尝试利用某些功能,则这是一个非常差的解决方案。

如果您以前没有使用过'heightForRowAtIndexPath'方法,但是想在不撤消UITableViewAutomaticDimension设置的情况下调试此错误,只需将其添加到代码中:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Section %ld Row %ld", (long)[indexPath section], (long)[indexPath row]);
    return UITableViewAutomaticDimension;
}

非常感谢。这对我很有帮助。起初我以为,那个问题出在另一个表格视图单元上。调试后,原来是另一个问题。
akozin

我想这样做,但是长,节和行是不确定的。您能说明一下这些在Swift中应该是什么吗?
DrWhat

9

XCode 6.1中似乎存在一个错误,如果使用自动布局会导致此问题,并且您没有为每个表格视图单元格的行高指定一个值,而是保留了“默认”值。只需选中每个单元格“行高”旁边的“自定义”复选框,警告就会消失。


2
如果您正在使用自动调整大小的单元格,则需要将行高设置为“默认”。
phatmann 2014年

1
这解决了警告。但是我相信它只会在TableView中使用静态单元格时出现
MontiRabbit 2014年

1
@phatmann此问题仅出现在静态单元格中,因此这些单元格不应自动调整大小。
ltm 2014年

如果用户使用放大的文字,@ ltm的大小自动设置的单元格在静态单元格中可能没有用?(您知道,在iPhone设置中可访问性下)
拜伦·科茨

我认为这不是错误,可能是垂直约束的问题,至少对于具有自动尺寸的表格视图,它们必须完全描述单元的高度。
juanjo

3

是的,即使在表格视图单元格中只有水平约束的情况下,您也会获得所有约束“满意”。我有同样的问题。您还需要添加垂直约束。这样做,该警告将消失。


3

约束可以出于布局目的而满足,但出于自动行高目的而并不满足。满意的布局意味着可以毫无歧义地布局内容。这将满足Interface Builder中的检查。

自动行高的令人满意的布局将意味着,除了上述内容之外,您还将约束单元格底部。

此处提供更多信息:检测到约束不明确地表明高度为零的情况


3

我在“表视图”大小检查器中使用了行高43(或<> 44),错误消失了。使用44我得到了错误。Xcode版本6.0.1。

-主持人删除了此答案,请不要这样做,它可以解决问题。这样可以为我解决问题,也可以为其他人解决。因此,您能不要再删除它吗?


2

我无法删除警告,但是为了使约束起作用,我将,new设置为iOS8,将tableview属性estimatedRowHeight设置为固定高度,并删除了heightForRowAtIndexPath实现。


如果它没有消除警告,则是由系统来弥补缺少的约束并将行高度==设置为cell.rowHeight属性。警告是关于自动修复属性的,如果它自动修复,则表示问题不存在?
Pedro Borges 2014年

2

如果收到该警告,则最有可能是因为您使用的是自动布局,并且单元格内部没有任何约束。

您应该停止使用自动布局,或者实施明确定义单元格高度的约束。

您可以通过取消选中右侧文件检查器中的“使用自动布局”选项来在界面构建器中关闭自动布局。

如果您选择使用自动布局并且单元格的高度是固定的,则实施适当的约束应该很容易。只需为单元格内容视图的子视图添加高度约束,并在子视图之间以及子视图与内容视图之间实现垂直空间约束。例如,如果您的单元格中有一个标签,则可以使用:

垂直约束

  1. 内容视图顶部和标签顶部之间的垂直空间约束
  2. 固定标签高度限制
  3. 标签底部和内容视图底部之间的垂直空间约束

水平约束

  1. 内容视图的前沿与标签的前沿之间的水平空间约束
  2. 标签的固定宽度约束
  3. 标签尾部和内容视图尾部之间的水平空间约束

我正在使用约束,就像问题中提到的那样,它们似乎都很高兴。
克里斯(Chris)

单元格内容视图的子视图是否有这些约束?他们看起来怎么样?您是否可能有一些不同的单元格?如果使用Frederic Bonner的解决方案将像元定义为具有固定高度,则约束将被覆盖。
wrightak


1

Swift强制返回高度修复了我的问题:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if(indexPath.row == 0){
       return CGFloat(131.0)
    }else if(indexPath.row == 8){
       return CGFloat(97.0)
    }else{
       return CGFloat(44.0)
    }
}

1

对于沼泽标准修补程序,没有约束,没有估计高度或过度设计了问题。我创建了一个默认项目,将tableview连接起来,但是忘记将高度委托放到view controller中。要简单地使此警告消失,您需要此。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 44;
}

在表的视图控制器中。


1

我在uitableviewcell中使用了mapView。我将地图视图的高度更改为设备屏幕尺寸的1/3。我遇到了同样的错误。我通过将缺失的约束添加到uitableviewcell的内容视图来修复该错误。

1)清除contentView约束。

2)将“重置为建议的常量”设置为contentView。

在此处输入图片说明

3)添加缺少的约束-如果有的话

4)我们确保内容视图具有所有必需的约束。 在此处输入图片说明


0

就我而言,这是因为我正在使用xib设计单元,而忘记了将该xib文件添加到目标中。

将那个xib文件添加到目标后,问题消失了


0

尽管此页面上的讨论讨论添加高度约束或手动返回heightHoldRowAtIndexPath中的44之类的rowHeights导致警告消失,但它们是多余的,因为这是Xcode中的错误,至少在版本6.3.2(6D2105)中可见。

如果在viewDidLoad中设置断点,即使在情节提要中指定行高为44,也会看到self.tableView.rowHeight = -1(UITableViewAutomaticDimension)。这是因为如果将行高保留为44,Apple会错误地假定您想要动态行高,因为它们没有为您提供用于指定首选项的标志。

以下是一些可能的解决方案及其结果:

  • 在情节提要中将行高设置为43或45(有效)。

  • 手动返回heightForRowAtIndexPath中的高度44(有效)。

  • 在UITableViewCell的元素及其contentView之间添加高度限制(有效)。

不幸的是,这些解决方案要么要求您更改设计,添加不必要的约束,要么添加不必要的代码来解决错误。我尝试了(我认为是)最简单的解决方案:

  • 在情节提要中将每个UITableViewCell的高度设置为44(自定义)(失败)。

我真的想要一个纯粹的情节提要解决方案,所以最后我尝试了:

  • 在情节提要中向UITableView添加用户定义的运行时属性,并用关于如何设置rowHeight的注释命名UITableView,以便将来的开发人员可以找到它:

在此处输入图片说明

在此处输入图片说明

这些错误在iOS开发中太常见了,迫使开发人员花费大量时间来衡量其解决方案从长远来看将如何影响可维护性。

由于很难找到一种在概念上可维护且不会混淆的正确解决方案,并且假设Apple将修复该错误并且在可预见的将来将44作为默认行高,则应使用约束或用户定义运行时属性解决方案可能是最可维护的。


0

我认为,这里发生了两件重要的事情。

1)如果您按住Ctrl +拖动,则使约束错误的方法非常容易。因此,请仔细检查您的设置是否正确。最好使用屏幕左侧的托盘绘制这些约束。

2)使用委托方法代替在ViewDidLoad或其他地方指定estimatedRowHeight

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

这立即为我解决了问题。


为什么要使用覆盖?
FractalDoctor 2015年

0

使用通用情节提要板或xib时,我也看到了此错误。如果您忽略为Any x Any size类指定适当的约束,则我会看到此错误。

苹果似乎已针对iOS9修复了此问题。该错误仅对我而言是8.4。


0

在这个错误与另一个错误(在不正确的地方)之间创建了与我想要的约束冲突的错误之间,我走了好几天。我什至让它在一个实例中工作,其中每个可见属性都与另一个相同。我发现的唯一解决方案是实现原子操作-使用xib创建一个全新的文件,然后再次开始重新连接复制粘贴旧代码的插座。这可能不是最好的解决方案,但是有时,如果看不到问题,则无可奈何。至少,原子化是回顾正在发生的事情的好方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.