2011-08-17 5 views
4

UIViewを含む無限のUIScrollViewを実装しました。 iOS5(シミュレータとiphone)でスクロールすると美しく動作します。しかし、iOS 4.3(シムと携帯電話)ではちょっと狂っていて、スクロールはそれよりも多くのビューを超えています(iOS5よりも約10〜15倍のビュー)。そして、もっと奇妙にするために、私がゆっくりドラッグすると期待通りに動くので、リリース後もスクロールを続けることはありません。Infinite UIScrollViewは、iOS4.3で奇妙な動作をします。iOS5ではありません。

セットアップはちょっと簡単ですが、私はUIScrollViewクラスを拡張します。そして、約1500ptの幅のUIViewを追加します。これは、私が上にスクロールしたいUIViewを追加します。画面をスクロールすると、画面がオフの場合にビューが追加および削除されます。

- (void)recenterIfNecessary { 
    CGPoint currentOffset = [self contentOffset]; 
    CGFloat contentWidth = [self contentSize].width; 
    CGFloat centerOffsetX = (contentWidth - [self bounds].size.width)/2.0; 
    CGFloat distanceFromCenter = fabs(currentOffset.x - centerOffsetX); 
    UIView *image; 

    if (distanceFromCenter > (contentWidth/4.0)) { 
     // Recenter the ScrollView so we never reach the edge 
     self.contentOffset = CGPointMake(centerOffsetX, currentOffset.y); 
     // Move visiblePhotos to new position to adjust to new contentOffset 
     for (image in visiblePhotos) { 
      CGPoint center = image.center; 
      center.x += (centerOffsetX - currentOffset.x); 
      image.center = center; 
     } 
    } 
} 

recenterIfNecessaryはここに呼び出されます:私は違いの間でパターンを見つけるしようとするログ位置とオフセットを試してみた

- (void)layoutSubviews { 
    [super layoutSubviews];  
    [self recenterIfNecessary]; 
    [self tileImagesFromMinX:minVisibleX toMaxX:maxVisibleX]; 
    //.... 
} 

私は私の問題は、このコードにしてあると思いますiOS4 & 5運があります。

私はhttp://developer.apple.com/videos/wwdc/2011/#advanced-scrollview-techniques(彼らはiOS5を使用しています)から概念といくつかのコードを得ました。 (visiblePhotos配列に入れている)

EDIT

写真は、このメソッドを使用して作成されています

- (CGFloat)placeNewImageOnRight:(CGFloat)rightEdge { 
    imageIndex = imageIndex < 0 ? ([reportItems count] - 1) : (imageIndex >= [reportItems count] ? 0 : imageIndex); 

    UIView *image = [self createItemContainer:[reportItems objectAtIndex:imageIndex]]; 
    [visiblePhotos addObject:image]; 

    CGRect frame = [image frame]; 
    frame.origin.x = rightEdge; 
    frame.origin.y = [imageContainerView bounds].size.height - frame.size.height; 

    [image setFrame:frame]; 

    imageIndex += 1; 

    return CGRectGetMaxX(frame); 
} 

- (CGFloat)placeNewImageOnLeft:(CGFloat)leftEdge { 
    imageIndex = imageIndex < 0 ? ([reportItems count] - 1) : (imageIndex >= [reportItems count] ? 0 : imageIndex); 

    UIView *image = [self createItemContainer:[reportItems objectAtIndex:imageIndex]]; 
    [visiblePhotos insertObject:image atIndex:0]; 

    CGRect frame = [image frame]; 
    frame.origin.x = leftEdge - frame.size.width; 
    frame.origin.y = [imageContainerView bounds].size.height - frame.size.height; 
    [image setFrame:frame]; 

    imageIndex -= 1; 

    return CGRectGetMinX(frame); 
} 

[self createItemContainer:[reportItems objectAtIndex:imageIndex]]

はphoto`が含まれているUIVeiwを作成します。

左右のメソッドは基本的に同じで、以下のメソッドで呼び出されます。 tileImagesFromMinXは、すべてのフレームで- (void)layoutSubviewsによって呼び出されます。

- (void)tileImagesFromMinX:(CGFloat)minVisibleX toMaxX:(CGFloat)maxVisibleX { 
    if ([visiblePhotos count] == 0) { 
     [self placeNewImageOnRight:minVisibleX]; 
    } 

    UIView *lastImage = [visiblePhotos lastObject]; 
    CGFloat rightEdge = CGRectGetMaxX([lastImage frame]); 
    while (rightEdge < maxVisibleX) { 
     rightEdge = [self placeNewImageOnRight:rightEdge]; 
    } 

    UIView *firstImage = [visiblePhotos objectAtIndex:0]; 
    CGFloat leftEdge = CGRectGetMinX([firstImage frame]); 
    while (leftEdge > minVisibleX) { 
     leftEdge = [self placeNewImageOnLeft:leftEdge]; 
    } 

    lastImage = [visiblePhotos lastObject]; 
    while ([lastImage frame].origin.x > maxVisibleX) { 
     [lastImage removeFromSuperview]; 
     [visiblePhotos removeLastObject]; 
     lastImage = [visiblePhotos lastObject]; 
    }  

    firstImage = [visiblePhotos objectAtIndex:0]; 
    while (CGRectGetMaxX([firstImage frame]) < minVisibleX) { 
     [firstImage removeFromSuperview]; 
     [visiblePhotos removeObjectAtIndex:0]; 
     firstImage = [visiblePhotos objectAtIndex:0]; 
    } 
} 
+0

あなたの 'visiblePhotos'を端からスクロールさせたい、あるいは何かラップアラートしますか? 'visiblePhotos'配列はどこに作成されますか? – jtbandes

+0

私は質問を更新しました。私の目標は、スクロールすることです。したがって、ユーザーは両方の方法を無限にスクロールでき、決して終わりには達しません。そして、すべての写真が正しい順序で並べ替えられます。 – fredrik

+0

写真は周りをループしますか?私は 'visiblePhotos'がどこから来るのか分かりません。 – jtbandes

答えて

6

私は調査の束をやって、あなただけのself.contentOffset = ...;を設定し、スクロールビューは/スクロールのiOS 4.3で適切に減速するように期待することはできませんことを決定しました。したがって、イメージのタイリングがなくても(イメージを削除してイメージコンテナビューに背景を置くと、実際にはこれがより明確にわかります)、recenterIfNecessaryの実装は4.3では動作しません(これはサンプルコードにも影響します)開発者サイトで!)。

残念ながら、これを回避するには-setContentOffset:をオーバーライドしてオフセットを変更してからsuperを呼び出すことが唯一の方法です。正しく動作させる方法については、this questionをご覧ください。私はこの方法がiOS 5でも動作することを願っています...

+0

私は 'recenterIfNecessary'の呼び出しを取り除き、' setContentOffset'をオーバーライドし、その中のcontentOffsetだけを処理します。今それはちょっとした作品です。時にはそれは少し周りにジャンプします。しかしそれは明確な改善です。私はもう少し数学を試してみるつもりです。 – fredrik

+0

@fredrik任意の運? – jtbandes

+0

それでも動作するようにはなりませんが、まだ飛び回っています。 – fredrik

関連する問題