WalkerZ's Blog

UICollectionViewCell 高度自适应

方法

其实就只是 cell 设置完约束之后,在 cell 中重写下面这个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 方式1
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
[self setNeedsLayout];
[self layoutIfNeeded];
UICollectionViewLayoutAttributes *attr = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
CGRect frame = attr.frame;
frame.size.width = layoutAttributes.size.width;
attr.frame = frame;
return attr;
}
// 方式2
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
[self setNeedsLayout];
[self layoutIfNeeded];
CGSize size = [self.contentView systemLayoutSizeFittingSize:layoutAttributes.size];
CGRect cellFrame = layoutAttributes.frame;
cellFrame.size.height = size.height;
layoutAttributes.frame = cellFrame;
return layoutAttributes;
}

实测这两种方式都有效。

然后设置 UICollectionViewFlowLayout 的 estimatedItemSize 属性。

遇到的问题

我在测试的时候碰到一个问题,控制台输出:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don’t want.
(
“NSAutoresizingMaskLayoutConstraint:0x600000096ad0 UIView:0x7fa8aff07130.height == 80”,

“NSLayoutConstraint:0x600000095810 UIScrollView:0x7fa8b1822800.height == 150”,

)
Will attempt to recover by breaking constraint
NSLayoutConstraint:0x600000095810 UIScrollView:0x7fa8b1822800.height == 150

这是说 cell 的那些约束无法同时存在。虽然界面看起来没什么问题,但还是不放心,搜索了一番,网上提供的解决方案在这里都无效。只好默默揣摩这段 log 的意思。

UIView:0x7fa8aff07130 是 cell 的 contentVIew,UIScrollView:0x7fa8b1822800 是其中一个子控件,UIView:0x7fa8aff07130.height == 80 是我设置的 UICollectionViewFlowLayout 的 estimatedItemSize 的 height,但是 scrollView 的 height 却等于150,大于80了。
也就是,初始的 cell 高度不够,导致加载 cell 的约束时约束出现冲突,所以出现了那些 log。这就十分尴尬了。

所以把 estimatedItemSize.height 改到 cell 最小高度就可以消除警告了。

(个人理解:因为 scrollView.height 是固定的,如果 cell.contentView 只有这样的高度固定的子控件,其实是没什么问题的,应该不会有警告。但是这里的情况是 scrollView 下面还有其他控件,y 相对于 scrollView,并且高度不定。这就可能导致那些控件的高度的约束出现负值,这就是警告了。)

(这文章写得相当新手orz)