4

我有一个 UICollectionView,有 6 个页面,启用了分页,还有一个 UIPageControl。我想要的是,当我来到最后一页时,如果我向右拖动, UICollectionView 会无缝地从第一页重新加载。

- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender
{

// The key is repositioning without animation
if (collectionView.contentOffset.x == 0) {
    // user is scrolling to the left from image 1 to image 10.
    // reposition offset to show image 10 that is on the right in the scroll view
    [collectionView scrollRectToVisible:CGRectMake(collectionView.frame.size.width*(pageControl.currentPage-1),0,collectionView.frame.size.width,collectionView.frame.size.height) animated:NO];
}
else if (collectionView.contentOffset.x == 1600) {
    // user is scrolling to the right from image 10 to image 1.
    // reposition offset to show image 1 that is on the left in the scroll view
    [collectionView scrollRectToVisible:CGRectMake(0,0,collectionView.frame.size.width,collectionView.frame.size.height) animated:NO];

}
pageControlUsed = NO;

}

它不像我想要的那样工作。我能做些什么?

4

3 回答 3

2

这是我的 UICollectionView 的最终结果(像 UIPickerView 一样的水平滚动):

@implementation UIInfiniteCollectionView

- (void) recenterIfNecessary {
    CGPoint currentOffset = [self contentOffset];
    CGFloat contentWidth = [self contentSize].width;
    // don't just snap to center, since this might be done in the middle of a drag and not aligned.  Make sure we account for that offset
    CGFloat offset = kCenterOffset - currentOffset.x;
    int delta = -round(offset / kCellSize);
    CGFloat shift = (offset + delta * kCellSize);
    offset += shift;
    CGFloat distanceFromCenter = fabs(offset);

    // don't always recenter, just if we get too far from the center.  Eliza recommends a quarter of the content width
    if (distanceFromCenter > (contentWidth / 4.0)) {
        self.contentOffset = CGPointMake(kCenterOffset, currentOffset.y);
        // move subviews back to make it appear to stay still
        for (UIView *subview in self.subviews) {
            CGPoint center = subview.center;
            center.x += offset;
            subview.center = center;
        }
        // add the offset to the index (unless offset is 0, in which case we'll assume this is the first launch and not a mid-scroll)
        if (currentOffset.x > 0) {
            int delta = -round(offset / kCellSize);
            // MODEL UPDATE GOES HERE
        }
    }
}

- (void) layoutSubviews { // called at every frame of scrolling
    [super layoutSubviews];
    [self recenterIfNecessary];
}

@end

希望这可以帮助某人。

于 2013-01-11T14:27:36.600 回答
1

我一直在使用 Street Scroller 示例为图像创建无限滚动条。这工作正常,直到我想pagingEnabled = YES; 围绕recenterIfNecessary 代码设置尝试调整并最终意识到它是contentOffset.x 必须匹配我希望在分页停止时可见的子视图的框架。这真的行不通,recenterIfNecessary因为你无法知道它会从layoutSubviews. 如果您确实对其进行了正确调整,则子视图可能会从您的手指下弹出。我在scrollViewDidEndDecelerating. 到目前为止,我还没有遇到快速滚动的问题。即使pagingEnabled是 NO,它也会工作并模拟分页,但如果是 YES,它看起来更自然。

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [super scrollViewDidEndDecelerating:scrollView];

    CGPoint currentOffset = [self contentOffset];

    // find the subview that is the closest to the currentOffset.
    CGFloat closestOriginX = 999999;
    UIView *closestView = nil;
    for (UIView *v in self.visibleImageViews) {
        CGPoint origin = [self.imageContainerView convertPoint:v.frame.origin toView:self];
        CGFloat distanceToCurrentOffset = fabs(currentOffset.x - origin.x);
        if (distanceToCurrentOffset <= closestOriginX) {
            closestView = v;
            closestOriginX = distanceToCurrentOffset;
        }
    }

    // found the closest view, now find the correct offset
    CGPoint origin = [self.imageContainerView convertPoint:closestView.frame.origin toView:self];
    CGPoint center = [self.imageContainerView convertPoint:closestView.center toView:self];
    CGFloat offsetX = currentOffset.x - origin.x;

    // adjust the centers of the subviews
    [UIView animateWithDuration:0.1 animations:^{
        for (UIView *v in self.visibleImageViews) {
            v.center = [self convertPoint:CGPointMake(v.center.x+offsetX, center.y) toView:self.imageContainerView];
        }
    }];
}
于 2013-02-13T01:31:43.720 回答
1

我没有使用 UICollectionView 进行无限滚动,但是在使用 UIScrollView 执行此操作时,您首先将内容偏移量(而不是使用 scrollRectToVisible)调整到您想要的位置。然后,您遍历滚动条中的每个子视图,并根据用户滚动的方向向右或向左调整它们的坐标。最后,如果任一端超出了您希望它们的范围,请将它们移到另一端。他们是来自苹果的关于如何进行无限滚动的非常好的 WWDC 视频,您可以在这里找到:http: //developer.apple.com/videos/wwdc/2012/

于 2012-12-10T03:19:48.693 回答