iOS8 - 约束模糊地表明高度为零

时间:2014-09-13 10:33:42

标签: objective-c uitableview ios8 heightforrowatindexpath

有谁知道如何调试这个?

  

仅警告一次:检测到约束模糊地建议tableview单元格的内容视图的高度为零的情况。我们正在考虑无意中崩溃并使用标准高度。

行具有由

设置的固定高度
- (CGFloat)tableView:(UITableView *)tableView 
           heightForRowAtIndexPath:(NSIndexPath *)indexPath{
   return 34.0;
}

所有constraints似乎都很开心......

18 个答案:

答案 0 :(得分:127)

强制返回高度和估计高度使警告在我的情况下消失。

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

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

另一个不需要这两个覆盖的解决方案就是在self.tableView.rowHeight = 44;或init方法中使用loadView

答案 1 :(得分:77)

还可以做的是从内容视图的顶部和底部添加垂直约束。这将使autolayout感到高兴(因为他现在知道如何计算自己的细胞高度)。

答案 2 :(得分:25)

如果您正在使用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;
}

答案 3 :(得分:9)

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

答案 4 :(得分:3)

是的,你得到所有的约束"快乐"即使在表视图单元格中只有项目的水平约束时也是如此。我有同样的问题。您还需要添加垂直约束。这样做,警告就会消失。

答案 5 :(得分:3)

为了布局的目的,约束可以很高兴,但对于自动行高的目的不满意。快乐的布局意味着内容可以毫不含糊地布局。这将满足Interface Builder中的检查。

自动行高的快乐布局意味着,除了上述内容之外,您还需要在单元格底部包含约束。

更多信息:Detected a case where constraints ambiguously suggest a height of zero

答案 6 :(得分:3)

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

- 这个答案被主持人删除了,请不要,它解决了问题。这解决了我的问题,也可能为其他人做。那么你能不能再删除它了。

答案 7 :(得分:2)

如果您收到警告,很可能是因为您使用的是自动布局,而且您的单元格内部没有任何限制。

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

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

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

垂直约束

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

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

答案 8 :(得分:2)

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

答案 9 :(得分:1)

您可以使用AutoLayout为您计算合适的高度。这是一篇关于iOS 8动态细胞高度的好文章:http://natashatherobot.com/ios-8-self-sizing-table-view-cells-with-dynamic-type/

答案 10 :(得分: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)
    }
}

答案 11 :(得分:1)

对于沼泽标准修复,没有约束,没有估计高度或过度设计问题。我创建了一个默认项目,连接了tableview但忘了将高度委托放在视图控制器中。要简单地让这个警告消失,你需要这个。

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

在您的表格视图控制器中。

答案 12 :(得分:1)

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

1)清除contentView约束。

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

enter image description here

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

4)我们确保内容视图具有所有必需的约束。 enter image description here

答案 13 :(得分:0)

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

答案 14 :(得分:0)

使用通用故事板或xib时,我也看到了这个错误。如果您忽略为Any x Any size class指定适当的约束,我会看到此错误出现。

Apple似乎已经为iOS9修复了此问题。该错误仅发生在8.4上。

答案 15 :(得分:0)

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

1)如果你进行ctrl +拖动,那么使约束变得非常容易。所以,仔细检查你是否正确完成了它。最好使用屏幕左侧的托盘来绘制这些约束。

2)不要在ViewDidLoad或其他地方指定estimatedRowHeight,而是使用委托方法

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

这立即解决了我的问题。

答案 16 :(得分:0)

虽然此页面上的答案讨论了添加高度限制或手动返回heightForRowAtIndexPath中的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,并将UITableView命名为其rowHeight的设置方式,以便将来的开发人员可以找到它:(工作): < / LI>

enter image description here

enter image description here

这些错误在iOS开发中非常普遍,迫使开发人员花费过多的时间来衡量他们的解决方案长期影响可维护性的后果。

由于找到一个可维护并且似乎没有混淆的概念上正确的解决方案是如此难以捉摸,并且假设Apple将修复该错误并且44将成为可预见的未来的默认行高,那么约束或用户定义的运行时属性解决方案可能是最易维护的。

答案 17 :(得分:0)

在我的情况下,这是因为我正在使用xib设计单元格,而我忘记将xib文件添加到目标。

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