无论滚动速度如何,每次滑动都可以将集合视图项目捕捉到一个

时间:2013-12-05 22:29:08

标签: ios7 uicollectionview uicollectionviewlayout

我在UICollectionViewFlowLayout的子类中使用Apple演示中的代码:

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    CGFloat offsetAdjustment = MAXFLOAT;
    CGFloat horizontalCenter = proposedContentOffset.x + self.collectionView.bounds.size.width / 2.;
    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0., self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);

    UICollectionViewLayoutAttributes *targetAttributes = nil;
    NSArray *attributes = [super layoutAttributesForElementsInRect:targetRect];
    for (UICollectionViewLayoutAttributes *a in attributes) {
        CGFloat itemHorizontalCenter = a.center.x;
        if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
            offsetAdjustment = itemHorizontalCenter - horizontalCenter;
            targetAttributes = a;
        }
    }

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

这在某种意义上起作用,无论何时我滑动/平移和释放,项目都会卡入到位。但建议的内容偏移量与滑动速度成正比。我想要做的是,无论我滑动多快/慢,集合视图只会紧接到当前居中的那个之前或之后的下一个项目。

我试过这样做:

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    NSInteger currentPage = (int)(self.collectionView.contentOffset.x / self.collectionView.bounds.size.width);
    if (proposedContentOffset.x > self.collectionView.contentOffset.x) {
        currentPage = (MIN(currentPage + 1, ((int)(self.collectionView.contentSize.width / self.collectionView.bounds.size.width)) - 1));
    }

    proposedContentOffset.x = self.collectionView.bounds.size.width * currentPage;

    CGFloat offsetAdjustment = MAXFLOAT;
    CGFloat horizontalCenter = proposedContentOffset.x + self.collectionView.bounds.size.width / 2.;
    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0., self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);

    UICollectionViewLayoutAttributes *targetAttributes = nil;
    NSArray *attributes = [super layoutAttributesForElementsInRect:targetRect];
    for (UICollectionViewLayoutAttributes *a in attributes) {
        CGFloat itemHorizontalCenter = a.center.x;
        if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
            offsetAdjustment = itemHorizontalCenter - horizontalCenter;
            targetAttributes = a;
        }
    }

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

但这不太对劲。有时它会跳过一个项目并在那之后捕捉到下一个项目(也就是说,它不会立即捕捉到我开始滚动的项目旁边的项目,而是紧接着下一个项目旁边的项目。)

有什么想法吗?

1 个答案:

答案 0 :(得分:14)

好的,所以我想通过制作与当前contentOffset相关的所有内容来使其工作:

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    if (proposedContentOffset.x > self.collectionView.contentOffset.x) {
        proposedContentOffset.x = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width / 2.;
    }
    else if (proposedContentOffset.x < self.collectionView.contentOffset.x) {
        proposedContentOffset.x = self.collectionView.contentOffset.x - self.collectionView.bounds.size.width / 2.;
    }

    CGFloat offsetAdjustment = MAXFLOAT;
    CGFloat horizontalCenter = proposedContentOffset.x + self.collectionView.bounds.size.width / 2.;
    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0., self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);

    NSArray *attributes = [super layoutAttributesForElementsInRect:targetRect];
    for (UICollectionViewLayoutAttributes *a in attributes) {
        CGFloat itemHorizontalCenter = a.center.x;
        if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
            offsetAdjustment = itemHorizontalCenter - horizontalCenter;
        }
    }

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