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]]
左右のメソッドは基本的に同じで、以下のメソッドで呼び出されます。 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];
}
}
あなたの 'visiblePhotos'を端からスクロールさせたい、あるいは何かラップアラートしますか? 'visiblePhotos'配列はどこに作成されますか? – jtbandes
私は質問を更新しました。私の目標は、スクロールすることです。したがって、ユーザーは両方の方法を無限にスクロールでき、決して終わりには達しません。そして、すべての写真が正しい順序で並べ替えられます。 – fredrik
写真は周りをループしますか?私は 'visiblePhotos'がどこから来るのか分かりません。 – jtbandes