如何使 collectionViewCell 仅按高度自动调整大小?
How make a collectionViewCell auto size only by height?
我使用了 collectionView 的自动调整流布局的功能
self.flow = [[UICollectionViewFlowLayout alloc] init];
self.flow.scrollDirection = UICollectionViewScrollDirectionVertical;
self.flow.sectionInset = UIEdgeInsetsZero;
self.flow.estimatedItemSize = CGSizeMake(320, 48);
我想让单元格按 CollectionView 的全宽宽度填充 (widthCell=widthCollectionView)
但我得到了整个尺寸的自动调整工作。我尝试使用 Content Compression/Hugging Priority - 无效。
CollectionView 的宽度等于 320px,我得到了标签内容大小的单元格大小。
我的手机看起来像
水平约束:H:|-8-[img(48)]-8-[label]-8-|
如何使自动调整大小仅适用于垂直而不适用于水平?
我找到了解决方案。
CollectionViewCell 有一个委托 preferredLayoutAttributesFittingAttributes
因此,此函数为您提供 layoutAttributes 设置为 estimatedItemSize
你需要做下一步(身高)
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
UICollectionViewLayoutAttributes *attr = [super preferredLayoutAttributesFittingAttributes:layoutAttributes]; //Must be called
CGRect frame = attr.frame;
frame.size.width = layoutAttributes.size.width; //Key here
attr.frame = frame;
return attr;
}
同样,您可以选择尺寸和宽度,因此高度保持不变 (frame.size.height = layoutAttributes.size.height)。
如果只是复制layoutAttributes并改变width,是没有效果的!
必须调用super.
其实你说的是约束优先级的问题。
要解决优先级约束问题,您应该以编程方式或直接从 InterFace Builder 更新 imageView Leading priority
999
和 label Trailing
优先级 999
。
通过使用我已经实施的 KVConstraintExtensionsMaster
以编程方式更新优先级,以更新任何没有 IBOutlet reference
Autolayout 约束的约束。
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell1" forIndexPath:indexPath];
[cell.imageView changeAppliedConstraintPriority:999 forAttribute:NSLayoutAttributeLeading];
[cell.label changeAppliedConstraintPriority:999 forAttribute:NSLayoutAttributeTrailing];
return cell;
}
之后你需要计算单元格的唯一高度
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat width = CGRectGetWidth(collectionView.bounds);
CGFloat height = /* do here some calculation for height */
return CGSizeMake(width, height);;
}
Dmitry Nelepov在swift.
中的解决方案
Swift 4
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
let attr = super.preferredLayoutAttributesFitting(layoutAttributes)
var frame = attr.frame
frame.size.width = layoutAttributes.size.width //Key here
attr.frame = frame
return attr
}
我使用了 collectionView 的自动调整流布局的功能
self.flow = [[UICollectionViewFlowLayout alloc] init];
self.flow.scrollDirection = UICollectionViewScrollDirectionVertical;
self.flow.sectionInset = UIEdgeInsetsZero;
self.flow.estimatedItemSize = CGSizeMake(320, 48);
我想让单元格按 CollectionView 的全宽宽度填充 (widthCell=widthCollectionView)
但我得到了整个尺寸的自动调整工作。我尝试使用 Content Compression/Hugging Priority - 无效。
CollectionView 的宽度等于 320px,我得到了标签内容大小的单元格大小。
我的手机看起来像
水平约束:H:|-8-[img(48)]-8-[label]-8-|
如何使自动调整大小仅适用于垂直而不适用于水平?
我找到了解决方案。
CollectionViewCell 有一个委托 preferredLayoutAttributesFittingAttributes
因此,此函数为您提供 layoutAttributes 设置为 estimatedItemSize
你需要做下一步(身高)
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
UICollectionViewLayoutAttributes *attr = [super preferredLayoutAttributesFittingAttributes:layoutAttributes]; //Must be called
CGRect frame = attr.frame;
frame.size.width = layoutAttributes.size.width; //Key here
attr.frame = frame;
return attr;
}
同样,您可以选择尺寸和宽度,因此高度保持不变 (frame.size.height = layoutAttributes.size.height)。
如果只是复制layoutAttributes并改变width,是没有效果的!
必须调用super.
其实你说的是约束优先级的问题。
要解决优先级约束问题,您应该以编程方式或直接从 InterFace Builder 更新 imageView Leading priority
999
和 label Trailing
优先级 999
。
通过使用我已经实施的 KVConstraintExtensionsMaster
以编程方式更新优先级,以更新任何没有 IBOutlet reference
Autolayout 约束的约束。
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell1" forIndexPath:indexPath];
[cell.imageView changeAppliedConstraintPriority:999 forAttribute:NSLayoutAttributeLeading];
[cell.label changeAppliedConstraintPriority:999 forAttribute:NSLayoutAttributeTrailing];
return cell;
}
之后你需要计算单元格的唯一高度
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat width = CGRectGetWidth(collectionView.bounds);
CGFloat height = /* do here some calculation for height */
return CGSizeMake(width, height);;
}
Dmitry Nelepov在swift.
中的解决方案Swift 4
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
let attr = super.preferredLayoutAttributesFitting(layoutAttributes)
var frame = attr.frame
frame.size.width = layoutAttributes.size.width //Key here
attr.frame = frame
return attr
}