我有一个UITableView在iOS 8下运行,我在故事板中使用约束的自动单元格高度。

我的一个单元格包含一个UITextView,我需要它根据用户输入收缩和展开-点击收缩/展开文本。

我通过在文本视图中添加一个运行时约束,并在响应用户事件时改变约束上的常数来做到这一点:

-(void)collapse:(BOOL)collapse; {

    _collapsed = collapse;

    if(collapse)
        [_collapsedtextHeightConstraint setConstant: kCollapsedHeight]; // 70.0
    else
        [_collapsedtextHeightConstraint setConstant: [self idealCellHeightToShowFullText]];

    [self setNeedsUpdateConstraints];

}

无论何时我这样做,我包装在tableView更新和调用[tableView setNeedsUpdateConstraints]:

[tableView beginUpdates];

[_briefCell collapse:!_showFullBriefText];

[tableView setNeedsUpdateConstraints];
// I have also tried 
// [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
// with exactly the same results.

[tableView endUpdates];

当我这样做的时候,我的单元格确实会扩展(并在做的时候动画),但我得到一个约束警告:

2014-07-31 13:29:51.792 OneFlatEarth[5505:730175] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

(

    "<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'(388)]>",

    "<NSLayoutConstraint:0x7f94dced2260 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...']-(15)-|   (Names: '|':UITableViewCellContentView:0x7f94de5773a0 )>",

    "<NSLayoutConstraint:0x7f94dced2350 V:|-(6)-[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...']   (Names: '|':UITableViewCellContentView:0x7f94de5773a0 )>",

    "<NSLayoutConstraint:0x7f94dced6480 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7f94de5773a0(91)]>"
 )

Will attempt to recover by breaking constraint 

<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'(388)]>

388是我计算的高度,UITextView上的其他约束是我从Xcode/IB中得到的。

最后一个是困扰我-我猜uiview - encapsulation - layout - height是计算单元格的高度时,它是第一次渲染-(我设置我的UITextView高度>= 70.0),但它似乎不正确,这个派生约束然后驳回更新用户cnstraint。

更糟糕的是,尽管布局代码说它试图打破我的高度限制,但它并没有-它继续重新计算单元格的高度,一切都按照我想要的方式绘制。

所以,什么是NSLayoutConstraint UIView-Encapsulated-Layout-Height(我猜它是计算的高度自动单元格大小),我应该如何去迫使它重新计算干净?


当前回答

我在集合视图单元格中遇到了类似的问题。

我通过降低链接到单元格底部的最终约束的优先级来解决这个问题(从视图的顶部到底部的链中的最后一个约束-这最终决定了它的高度)到999。

细胞的高度是正确的,警告就消失了。

其他回答

我能够解决这个错误通过删除一个假cell.layoutIfNeeded(),我在我的tableView的cellForRowAt方法。

另一种可能性:

如果你使用auto layout来计算单元格高度(contentView的高度,大多数时候如下所示),如果你有uitableview分隔符,你需要添加分隔符高度,以便返回单元格高度。一旦你得到正确的高度,你就不会有自动布局警告。

- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
   [sizingCell setNeedsLayout];
   [sizingCell layoutIfNeeded];
   CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
   return size.height; // should + 1 here if my uitableviewseparatorstyle is not none

}

我有一个类似的场景:一个只有一行单元格的表格视图,其中有几行UILabel对象。我使用iOS 8和自动布局。

当我旋转时,我得到了错误的系统计算的行高(43.5远小于实际高度)。它看起来是这样的:

"<NSLayoutConstraint:0x7bc2b2c0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7bc37f30(43.5)]>"

这不仅仅是一个警告。我的表格视图单元格的布局是可怕的-所有的文本重叠在一个文本行。

让我惊讶的是,下面这一行神奇地“解决”了我的问题(自动布局没有抱怨,我在屏幕上得到了我所期望的):

myTableView.estimatedRowHeight = 2.0; // any number but 2.0 is the smallest one that works

不管有没有这句话:

myTableView.rowHeight = UITableViewAutomaticDimension; // by itself this line only doesn't help fix my specific problem

设置该视图。translatesAutoresizingMaskIntoConstraints = NO;应该能解决这个问题。

No one answered it how to solve the case in storyboard. You have the case of mine, top bottom constraint with fixed height with priority 1000. That is why, when first time loading , as the table view cell height is 0, tries to set the element with the fixed height, causing a constraint conflict. (I am trying to insert 40 pixel in a 0 pixel height area, so compiler tries discarding the 40 pixel height). Once the tableview loaded, it will not generate (Like pop back to the tableview or switching tab bar tab)

所以将优先级从必需的@1000更改为高@750或低@250。第一次加载时,不考虑低优先级,然后在layoutSubviews()中调整所有约束的大小