因此,UITableView支持基本上“无限”滚动。可能有限制,但是该家伙可以滚动很长时间。我想用UIScrollView模仿这种行为,但有两个根本性障碍:
1)scrollView.contentSize在创建时固定。 2)缩放可能会炸毁任何懒惰加载方案,因为它可能导致无限数据爆炸。
其他人是否考虑过这个想法?是的,我知道,我们实际上在谈论重新创建Google Maps。非常感谢您提供任何见解。
干杯, 道格
因此,UITableView支持基本上“无限”滚动。可能有限制,但是该家伙可以滚动很长时间。我想用UIScrollView模仿这种行为,但有两个根本性障碍:
1)scrollView.contentSize在创建时固定。 2)缩放可能会炸毁任何懒惰加载方案,因为它可能导致无限数据爆炸。
其他人是否考虑过这个想法?是的,我知道,我们实际上在谈论重新创建Google Maps。非常感谢您提供任何见解。
干杯, 道格
我刚刚完成了无限滚动的实现。 我的实现中,UITableViewCell 包含一个 scrollView 和导航按钮。scrollView 包含 x 个视图,每个视图的宽度都相同。这些视图水平对齐,并启用了分页。
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.showsHorizontalScrollIndicator = NO;
我的代码逻辑如下:
然后我调用一个函数,在循环中计算每个视图的位置(每次检测到滚动时,也需要调用此函数)。 它总是取数组的第一个元素,并将其框架设置为(0,0,...,...),第二个元素为(i*宽度,0,...,...)等等。 被调用的函数如下:
- (void)updateOffsetsOfViews{
int xpos = 0;
for (int i=0; i<[views count]; i++) {
UIImageView *_view = [views objectAtIndex:i];
CGRect aFrame = _view.frame;
aFrame.origin.x = xpos;
aFrame.origin.y = 0.0;
_view.frame = aFrame;
xpos += viewWidth;
}
float center = 0;
if(fmod([views count],2) == 1){
center = viewWidth * ([views count]-1)/2;
}else {
center = viewWidth * [views count]/2;
}
[scrollView setContentOffset:CGPointMake(center, 0)];
lastOffset = center;
}
然后(仍在初始化过程中),我添加了一个观察者
[scrollView addObserver:self forKeyPath:@"contentOffset" options:0 context:nil];
每次scrollView中的内容发生更改时,都会调用(observeValueForKeyPath)函数,它看起来像这样:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
UIImageView *_viewFirst = (UIImageView *)[views objectAtIndex:0];
if ( fmod([scrollView contentOffset].x,viewWidth) == 0.0) {
if ([scrollView contentOffset].x > lastOffset) {
[views removeObjectAtIndex:0];
[views addObject:_viewFirst];
[self updateOffsetsOfViews];
}else if ([scrollView contentOffset].x < lastOffset) {
UIImageView *_viewLast = (UIImageView *)[views lastObject];
[views removeLastObject];
[views insertObject:_viewLast atIndex:0];
[self updateOffsetsOfViews];
}
}
}
在dealloc或viewDidUnload方法中(取决于您的实现方式),不要忘记移除观察者。
[scrollView removeObserver:self forKeyPath:@"contentOffset"];
希望这能帮到你,你可能会注意到一些额外的开销,但在我的实现中,我还支持像滚动5页(嗯...无限)和自动滚动等功能,所以你可能会看到一些可以丢弃的东西。虽然无法真正实现无限UIScrollView,但是有一些简单的技巧可以用来模拟该行为。
contentSize
:让滚动视图处理一些固定大小的视图,并在启动或实例化时设置内容偏移量,以便您看到受处理视图的中心部分。然后只需监视内容偏移量(使用KVO或其他方法),如果接近任何边缘,则更新视图内容(适当偏移)并将滚动视图的contentOffset
属性重置为回到中间。setContentOffset
会取消任何正在进行的滚动并使其突然停止。我不知道如何确定视图移动的速度,也不知道如果能确定速度的话如何重新启动滚动。 - GrumdrigsetContentOffset:animated:
会取消当前的滚动,但是 setContentOffset:
不会... 在 UIScrollView
的子类中重写 setContentOffset:
并调整偏移量可以解决问题!(至少在 iOS SDK 4.3 上是这样) - Damien DebincontentOffset
会多次变化,不仅是按页面分页,而且还会随着动画中的每一步而变化。也许将contentSize
设置为巨大值,然后移动有限数量的基础视图以跟踪视图位置(如平铺示例中所示)可以解决问题。
为了减轻最终到达边缘并不得不突然重新调整视图(取消当前正在运动的任何滚动)的可能性,可以在视图静止时定期重新调整视图中心。
无论如何,这就是我要尝试的。