4

6ページのUICollectionViewがあり、ページングが有効になっていて、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

無限スクロールにUICollectionViewを使用したことはありませんが、UIScrollViewを使用する場合は、最初にコンテンツオフセットを(scrollRectToVisibleを使用する代わりに)目的の場所に調整します。次に、スクローラーの各サブビューをループし、ユーザーがスクロールしていた方向に基づいて、それらの座標を右または左に調整します。最後に、どちらかの端が希望の範囲を超えている場合は、もう一方の端に移動します。彼らはあなたがここで見つけることができる無限のスクロールをする方法についてのアップルからの非常に良いWWDCビデオです:http://developer.apple.com/videos/wwdc/2012/

于 2012-12-10T03:19:48.693 に答える
1

私はStreetScrollerサンプルを使用して、画像用の無限スクローラーを作成してきました。これpagingEnabled = YES; は、recenterIfNecessaryコードを微調整して、ページングが停止したときに表示したいサブビューのフレームと一致する必要があるのはcontentOffset.xであることに最終的に気付くまでは問題なく機能します。recenterIfNecessaryから呼び出されることを知る方法がないため、これは実際には機能しませんlayoutSubviews。正しく調整すると、指の下からサブビューが飛び出すことがあります。で調整しscrollViewDidEndDeceleratingます。これまでのところ、高速スクロールに問題はありません。NOの場合でも動作し、ページングをシミュレートしpagingEnabledますが、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 に答える