【发布时间】:2011-10-28 18:39:11
【问题描述】:
我已经实现了一个包含 UIView 的无限 UIScrollView。在 iOS5(模拟器和 iphone)中滚动时效果很好。但在 iOS 4.3(sim 和手机)中,它有点疯狂,滚动通过的浏览量比它应该的要多(大约比 iOS5 多 10-15 倍)。为了让它更奇怪,如果我慢慢拖动它会按预期工作,所以在我释放后它不会继续滚动。
设置有点简单,我扩展了 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 数组中)使用以下方法创建:
- (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]] 创建一个包含照片的 UIVeiw。
left 和 right 方法基本相同,由下面的方法调用。 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数组是在哪里创建的? -
我更新了问题。我的目标是拥有无尽的滚动。因此,用户可以双向滚动到无穷大,永远不会到达终点。所有照片都按正确的顺序重新排列。
-
照片是否循环播放?我不知道
visiblePhotos来自哪里。 -
照片循环播放。
visiblePhotos是在我的 ScrollView 子类的 init 方法中声明的 NSMutableArray。照片仅从placeNewImageOnLeft、placeNewImageOnRight和(void)tileImagesFromMinX:(CGFloat)minVisibleX toMaxX:(CGFloat)maxVisibleX中添加/删除 -
抱歉,没有注意到编辑。我再看看。
标签: iphone objective-c uiscrollview