我有一个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。

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

其他回答

在我的案例中,问题是UITableViewCell中的垂直UIStackView,这是基于数据显示/隐藏行。我使用自动调整单元格大小,单元格本身总是显示正确,具有正确的高度。只是日志中充满了关于uiview - encapsulation - layout - height的约束异常。

我通过为UIStackView的顶部和底部约束设置一个较低的优先级来解决这个问题(999而不是默认的1000)。现在没有约束异常,并且表的外观和行为完全相同。

与其通知表视图更新它的约束,不如尝试重新加载单元格:

[tableView beginUpdates];

[_briefCell collapse:!_showFullBriefText];

[tableView reloadRowsAtIndexPaths:@[[tableView indexPathForCell:_briefCell]] withRowAnimation:UITableViewRowAnimationNone];

[tableView endUpdates];

uiview - encapsulation - layout - height可能是表格视图在初始加载期间为单元格计算的高度,基于单元格当时的约束。

在花了几个小时对这个bug挠头之后,我终于找到了一个适合我的解决方案。我的主要问题是,我有多个nibs注册为不同的单元格类型,但一个单元格类型被允许有不同的大小(不是所有实例的单元格将是相同的大小)。当tableview试图让该类型的单元格出队列时,问题就出现了,而它恰好有不同的高度。我通过设置来解决

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; self.frame = CGRectMake(0,0, self.frame.size.width,{正确的高度});

当细胞有数据计算它的大小时。 我觉得可以

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

类似的

cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; cell.frame = CGRectMake(0,0, self.frame.size.width,{正确的高度});

希望这能有所帮助!

我有一个类似的场景:一个只有一行单元格的表格视图,其中有几行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

我也有同样的问题。对我来说,误差是0.5像素。

2020-08-06 21:33:20.947369+0530 DemoNestedTableView[4181:384993] [LayoutConstraints] 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. 
(

        "<NSLayoutConstraint:0x600000a3abc0 UICollectionView:0x7fde0780c200.height == 326   (active)>",
        "<NSLayoutConstraint:0x600000a3ae40 V:|-(0)-[UICollectionView:0x7fde0780c200]   (active, names: '|':UITableViewCellContentView:0x7fde05e0cb10 )>",
        "<NSLayoutConstraint:0x600000a3af30 V:[UICollectionView:0x7fde0780c200]-(0)-|   (active, names: '|':UITableViewCellContentView:0x7fde05e0cb10 )>",
        "<NSLayoutConstraint:0x600000a2a4e0 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7fde05e0cb10.height == 326.5   (active)>"
    )

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600000a3abc0 UICollectionView:0x7fde0780c200.height == 326   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

只要加上这个就行了。

self.tableView.separatorStyle = .none