targetContentOffsetForProposedContentOffset:withScrollingVelocity无子类化UICollectionViewFlowLayout

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (65)

我的应用程序中有一个非常简单的collectionView(只是一行方形缩略图)。

我想拦截滚动,以便偏移总是在左侧留下完整的图像。目前它滚动到任何地方,并会留下切断的图像。

无论如何,我知道我需要使用该功能

- (CGPoint)targetContentOffsetForProposedContentOffset:withScrollingVelocity

做到这一点,但我只是使用一个标准UICollectionViewFlowLayout。我没有继承它。

有没有任何方法来拦截这个没有子类化UICollectionViewFlowLayout

谢谢

提问于
用户回答回答于

好吧,答案是否定的,没有UICollectionViewFlowLayout子类就无法做到这一点。

然而,子类化对于将来阅读这篇文章的人来说是非常容易的。

首先,我设置了子类调用。MyCollectionViewFlowLayout然后,在接口生成器中,我将集合视图布局更改为自定义,并选择了我的流布局子类。

因为你是这样做的,所以你不能在IB中指定项目大小等等,所以在MyCollection ViewFlowLayout.m中我有:

- (void)awakeFromNib
{
    self.itemSize = CGSizeMake(75.0, 75.0);
    self.minimumInteritemSpacing = 10.0;
    self.minimumLineSpacing = 10.0;
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    self.sectionInset = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
}

这为我设置了所有尺寸和滚动方向。

然后

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    CGFloat offsetAdjustment = MAXFLOAT;
    CGFloat horizontalOffset = proposedContentOffset.x + 5;

    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);

    NSArray *array = [super layoutAttributesForElementsInRect:targetRect];

    for (UICollectionViewLayoutAttributes *layoutAttributes in array) {
        CGFloat itemOffset = layoutAttributes.frame.origin.x;
        if (ABS(itemOffset - horizontalOffset) < ABS(offsetAdjustment)) {
            offsetAdjustment = itemOffset - horizontalOffset;
        }
    }

    return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}

这确保滚动结束在左侧边缘的边缘为5.0。

这就是我要做的。我根本不需要在代码中设置流布局。

用户回答回答于

我建议的替代实现具有与之前提出的相同的分页,但处理用户在页面之间翻阅

 #pragma mark - Pagination
 - (CGFloat)pageWidth {
     return self.itemSize.width + self.minimumLineSpacing;
 }

 - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
 {           
        CGFloat rawPageValue = self.collectionView.contentOffset.x / self.pageWidth;
        CGFloat currentPage = (velocity.x > 0.0) ? floor(rawPageValue) : ceil(rawPageValue);
        CGFloat nextPage = (velocity.x > 0.0) ? ceil(rawPageValue) : floor(rawPageValue);

        BOOL pannedLessThanAPage = fabs(1 + currentPage - rawPageValue) > 0.5;
        BOOL flicked = fabs(velocity.x) > [self flickVelocity];
        if (pannedLessThanAPage && flicked) {
            proposedContentOffset.x = nextPage * self.pageWidth;
        } else {
            proposedContentOffset.x = round(rawPageValue) * self.pageWidth;
        }

        return proposedContentOffset;
 }

 - (CGFloat)flickVelocity {
     return 0.3;
 }

扫码关注云+社区