自动调整 UITableViewCell 大小:无法同时满足约束

Posted

技术标签:

【中文标题】自动调整 UITableViewCell 大小:无法同时满足约束【英文标题】:Auto-resize UITableViewCell: Unable to simultaneously satisfy constraints 【发布时间】:2017-06-22 03:28:56 【问题描述】:

我正在尝试实现一个 UITableViewCell,它会自动调整其高度以适应可用内容。我现在有以下布局,但是每当我运行程序时,调试器都会抛出各种“无法同时满足约束”错误。我设置约束的方式有问题吗?

[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:0x60800009c2f0 UIImageView:0x7fd389002f50.height == 60   (active)>",
    "<NSLayoutConstraint:0x60800009a8b0 UIImageView:0x7fd389002f50.top == UITableViewCellContentView:0x7fd389009b20.topMargin + 4   (active)>",
    "<NSLayoutConstraint:0x608000097ca0 UITableViewCellContentView:0x7fd389009b20.bottomMargin >= UIImageView:0x7fd389002f50.bottom + 4   (active)>",
    "<NSLayoutConstraint:0x600000097d40 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7fd389009b20.height == 80   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x60800009c2f0 UIImageView:0x7fd389002f50.height == 60   (active)>

为了完整起见,这是我用于测试的简单代码。

“ListViewController.m”

- (void)viewDidLoad 
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    tableView.rowHeight = UITableViewAutomaticDimension;
    tableView.estimatedRowHeight = 40;


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    return 40;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    ListTableViewCell *cell = (ListTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"ListCell" forIndexPath:indexPath];

    [self configureCell:cell atIndexPath:indexPath];
    return cell;


- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
    // Return NO if you do not want the specified item to be editable.
    return NO;


- (void)configureCell:(ListTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    cell.hasProfile = (arc4random_uniform(10) < 3);
    cell.hasSecondField = (arc4random_uniform(10) < 3);

ListViewCell.h

@interface ListTableViewCell : UITableViewCell 
    IBOutlet NSLayoutConstraint *pictureWidthConstraint;
    IBOutlet NSLayoutConstraint *pictureHeightConstraint;
    IBOutlet NSLayoutConstraint *pictureBottomTrailingConstraint;
    IBOutlet NSLayoutConstraint *subheaderHeightConstant;

    IBOutlet UILabel *subheaderLabel;


@property (nonatomic, assign) BOOL hasProfile;
@property (nonatomic, assign) BOOL hasSecondField;

@end

ListViewCell.m

- (void)setHasProfile:(BOOL)hasProfile 
    _hasProfile = hasProfile;

    if (!hasProfile) 
        pictureHeightConstraint.constant = 0;
        pictureWidthConstraint.constant = 0;
    
    else 
        pictureHeightConstraint.constant = 60;
        pictureWidthConstraint.constant = 60;
    


- (void)setHasSecondField:(BOOL)hasSecondField 
    _hasSecondField = hasSecondField;

    if (!hasSecondField) 
        subheaderLabel.text = @"";
        subheaderHeightConstant.constant = 0;
    
    else 
        subheaderLabel.text = @"Second Label";
        subheaderHeightConstant.constant = 21;
    

【问题讨论】:

显然错误地提到了问题在于 Imageview 高度。您已经给出了 imageview = 60 的高度以及底部和顶部约束。这就是它向您发出未满足约束的警告的原因。移除 imageview 的底部约束,看看是否报错。 在这里查看我关于自动布局的答案 TableCell ,,,,, ***.com/a/43656451/4466607 @PF1 尝试在uitableviewcell的inspector中为行高设置checkBox“Custom”。并删除 uitableviewcell 的约束约束 80(如果存在)。另外我会删除 pictureHeightConstraint.constant = 0 和 subheaderHeightConstant.constant = 0 【参考方案1】:

错误表明存在与您的 imageview 的高度 60 冲突的其他约束,并且此约束已被修改,以便可以满足所有约束。

您可以调整以查看哪个约束与该高度冲突,或者您可以自己打破它。为此,请单击图像高度上的编辑按钮,然后将优先级更改为 999

【讨论】:

我建议在底部使用 >= 约束,这样可以修复警告并且仍然受到尊重。

以上是关于自动调整 UITableViewCell 大小:无法同时满足约束的主要内容,如果未能解决你的问题,请参考以下文章

如何让 UITableView 行高自动调整为 UITableViewCell 的大小?

自动调整 UITableViewCell 大小:无法同时满足约束

让 UITableViewCell 使用自动布局调整自身大小

自动调整子类 UITableViewCell 子视图的大小

在 UITableViewCell 中自动调整 UILabel 的大小

字体更改时自动uiLabel和uiTableViewCell调整大小的iphone代码?