如何使collectionViewCell自动调整高度?

时间:2015-11-18 03:00:23

标签: ios autolayout uicollectionview uicollectionviewcell

我使用了collectionView的自动调整流程布局的功能

self.flow = [[UICollectionViewFlowLayout alloc] init];
self.flow.scrollDirection = UICollectionViewScrollDirectionVertical;
self.flow.sectionInset = UIEdgeInsetsZero;
self.flow.estimatedItemSize = CGSizeMake(320, 48);

我希望单元格将按宽度全宽度填充CollectionView(widthCell = widthCollectionView)

但我得到了整个尺寸的自动调整工作。我尝试使用内容压缩/拥抱优先级 - 不起作用。

当CollectionView的宽度等于320px时,我得到了标签内容大小的单元格大小。

我的手机看起来像 enter image description here

约束水平:H:| -8- [img(48)] - 8- [label] -8- |

如何使自动调整仅适用于垂直而不适用于水平?

3 个答案:

答案 0 :(得分:12)

我找到了解决方案。

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并更改宽度,则无效!

你必须打电话给超级。

答案 1 :(得分:3)

实际上你就在这里是约束优先的问题。

要解决优先级约束问题,您应该以编程方式或直接从InterFace Builder更新imageView Leading priority 999label 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);;
}

答案 2 :(得分:-1)

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
}