程序员

UITableViewCell自动计算高度时的约束警告

2018-10-21  本文已影响24人  LittleYuz

具体业务

UITableViewCell 中嵌套一个 UICollectionView,Cell 的高度需要根据 CollectionView items 个数动态变化

image

遇到的问题

最后实现的效果是没有问题的,但会出现这样的约束警告

[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. 
[
    <MASLayoutConstraint:0x600002c6e6a0 UILabel:0x7ffc5fcf4bc0.top == XBHDemandRegionHotCitiesCell:0x7ffc611b3a00.top + 15>,
    <MASLayoutConstraint:0x600002c6ed60 UICollectionView:0x7ffc60a93c00.top == UILabel:0x7ffc5fcf4bc0.bottom + 5>,
    <MASLayoutConstraint:0x600002c6edc0 UICollectionView:0x7ffc60a93c00.bottom == XBHDemandRegionHotCitiesCell:0x7ffc611b3a00.bottom - 10>,
    <MASLayoutConstraint:0x600002c6efa0 UICollectionView:0x7ffc60a93c00.height == 70>,
    <NSLayoutConstraint:0x600002b52c60 DemandRegionHotCitiesCell:0x7ffc611b3a00.height == 44.3333>
]

Will attempt to recover by breaking constraint 
<MASLayoutConstraint:0x600002c6efa0 UICollectionView:0x7ffc60a93c00.height == 70>

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.

强迫症表示真的不能忍!!!

分析问题的根源

从警告中可以看到,Cell 有一个高度为 44.3333 的高度约束, 与 CollectionView 的高度为70约束产生了冲突,那么Cell的高度为44.3333的高度约束是从何而来的呢?

- (void)setCities:(NSArray<XBHRegion *> *)cities {
    _cities = [cities copy];
    [self.collectionView reloadData];
    NSInteger rowCount = ceil(_cities.count / ColumnCount);
    NSInteger spcingCount = MAX(rowCount - 1, 0);
    CGFloat collectionViewHeight = self.flowLayout.minimumLineSpacing * spcingCount + self.flowLayout.itemSize.height * rowCount;
    [self.collectionView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.height.mas_equalTo(collectionViewHeight);
    }];
}

更新 CollectionView 的高度是在上述代码中实现的,那么初次赋值时,cities的个数为0,导致 Cell 高度为 44.3333
所以猜想在cities有值时,系统在重新 layout 时,并没有把原先 高度为 44.3333 的约束移除,产生了约束冲突警告。

解决思路

Q:如果把这个 UICollectionView 的换成一个 UILabel 会不会产生警告呢?
A:答案当然是不会的,这种业务以前已经做过多次。
Q:那么为什么换成 UILabel 就不会呢?
A:是不是要反过来想,UILabel 是没有设置高度约束的,他是如何确定高度来“撑大” Cell的?

到这里,想必大家已经知道答案了。UILabel 是根据其内容来自动计算大小的,也就是intrinsicContentSize,转换为约束的优先级是 ContentHuggingPriority 默认是 750,而我们给 UICollectionView 添加的高度约束默认是 1000 的, 那么改一下不就ok了!

 make.height.mas_equalTo(collectionViewHeight).priorityMedium()

大功告成!!!

上一篇下一篇

猜你喜欢

热点阅读