具体业务
UITableViewCell 中嵌套一个 UICollectionView,Cell 的高度需要根据 CollectionView items 个数动态变化
遇到的问题
最后实现的效果是没有问题的,但会出现这样的约束警告
[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()
大功告成!!!