UIScrollView的.有关实现"无限"滚动/缩放的任何想法?

dug*_*gla 20 iphone cocoa-touch uiscrollview

因此,UITableView基本上支持"无限"滚动.可能有一个限制,但吸盘可以滚动looonnnggg时间.我想用UIScrollView模仿这种行为,但有两个基本障碍:

1)scrollView.contentSize在创建时被修复.2)缩放可以将任何延迟加载方案都吹到地狱,因为它可能导致infinte数据爆炸.

让其他人思考这个想法吗?是的,我知道,我们本质上是在谈论在这里重新创建谷歌地图.任何见解都将非常感激.

干杯,道格

All*_*one 13

我刚刚完成了为我实现的英文卷轴.在我的实现中,我有UITableViewCell,带有scrollView和Navigationbuttons.scrollView包含具有相同宽度的x视图.视图是水平的,并且启用了分页.

scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.showsHorizontalScrollIndicator = NO;
Run Code Online (Sandbox Code Playgroud)

我的codelogic如下:

  1. 在我的初始化函数中
    • 创建所有视图(对于scrollview)和
    • 把它们放到一个数组中
    • 将它们添加到scrollView
  2. 然后我调用一个函数,在循环中计算每个视图的位置(每次检测到滚动时,也需要调用此函数).它始终采用数组的第一个元素并将帧设置为(0,0,...,...),第二个元素设置为(i*width,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;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后(仍在初始化过程中)我添加一个观察者

    [scrollView addObserver:self forKeyPath:@"contentOffset" options:0 context:nil];
    
    Run Code Online (Sandbox Code Playgroud)

    所以每当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];
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在dealloc或viewDidUnload中(取决于你如何实现它)不要忘记删除观察者.

    [scrollView removeObserver:self forKeyPath:@"contentOffset"];   
    
    Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助,您可能会注意到一些开销,但在我的实现中,我也支持同时滚动5页(嗯...无限制)和自动滚动等等,这样您可能会看到可能被丢弃的东西.


Tim*_*Tim 10

虽然不可能有一个真正无限的UIScrollView,但你可以使用一些简单的技巧来模拟这种行为.

  1. 处理修复contentSize:使用滚动视图处理一些固定大小的视图,并在启动或实例化时设置内容偏移量,以便您可以看到处理视图的中间位置.然后只需观察内容偏移(使用KVO或其他方法),如果您靠近任何边缘,请使用一组新内容(适当偏移)更新视图内容,并将滚动视图的contentOffset属性重置为中间位置.
  2. 处理缩放:做类似的事情,这次只在滚动视图上观看缩放系数.每当它到达某一点时,对您呈现的任何数据进行一些操作,使其显示为缩放,然后将缩放系数重置为1.0.例如,如果您正在滚动图像并将其缩放为两倍大,则以编程方式应用某种变换以使图像大两倍,然后将滚动视图的缩放系数重置为1.0.图像仍将显示为放大,但滚动视图将能够根据需要继续放大.(谷歌地图更进了一步,它在用户缩放时延迟加载更详细的视图 - 您可能会也可能不会选择实现此功能.)

  • 这个解决方案的问题是`setContentOffset`取消正在发生的任何滚动并且运动突然停止.我不知道如何确定视图移动的速度,或者如果我这样做,如何重新启动该动作. (4认同)
  • 这里有一个链接http://iphonedevelopment.blogspot.com/2009/02/kvo-and-iphone-sdk.html为任何不知道那是什么的人解释KVO.就像我没有. (2认同)
  • 似乎`setContentOffset:animated:`取消当前滚动,但不取消`setContentOffset:`...在`UIScrollView`的后代重写`setContentOffset:`并调整偏移量工作!(至少在iOS SDK 4.3上) (2认同)