任何滚动都会调用UICollectionViewLayout prepareLayout

时间:2013-04-09 04:26:25

标签: ios uicollectionview uicollectionviewlayout

在实现自定义UICollectionViewLayout子类时发现了这种奇怪的行为。我设置了除collectionViewContentSize之外的子类方法。所有细胞出现在我预期的位置,但contentView太长了。看起来应该是它的两倍。

我实施了以下方法以获得正确的contentSize。虽然,它现在是预期值,但每次视图滚动一个像素时都会调用prepareLayout。这意味着如果我从0,0滑动到0,500,prepareLayout被调用500次!

我的collectionViewContentSize有什么可能导致这种情况?

- (CGSize)collectionViewContentSize {
    UICollectionViewLayoutAttributes *leftAttributes = (UICollectionViewLayoutAttributes *)self.layoutInfo[@"segmentCell"][[NSIndexPath indexPathForItem:[self.collectionView numberOfItemsInSection:0]-1 inSection:0]];
    UICollectionViewLayoutAttributes *rightAttributes = (UICollectionViewLayoutAttributes *)self.layoutInfo[@"segmentCell"][[NSIndexPath indexPathForItem:[self.collectionView numberOfItemsInSection:1]-1 inSection:1]];
    float leftHeight = leftAttributes.frame.size.height + leftAttributes.frame.origin.y;
    float rightHeight = rightAttributes.frame.size.height + rightAttributes.frame.origin.y;
    float maxHeight = leftHeight > rightHeight ? leftHeight : rightHeight;
    return CGSizeMake(self.collectionView.bounds.size.width, maxHeight);
}

2 个答案:

答案 0 :(得分:10)

虽然根据文档[0] shoulInvalidateLayoutForBoundsChange:默认情况下应该返回NO,但它不是。一旦我实现它并且在所有情况下都返回NO,则不再调用每个边界更改prepareLayout。这似乎是UICollectionViewLayout中的一个错误。

[0] http://developer.apple.com/library/ios/#documentation/uikit/reference/UICollectionViewLayout_class/Reference/Reference.html

答案 1 :(得分:0)

之所以会发生这种情况,是因为在使用自定义布局时,您可能希望根据内容偏移量来更改单元格的大小,例如当您向上滑动iPhone X时,Y值决定了单元的大小。这使您不必为可能需要的特定效果而处理单独的手势识别器。