UIScrollView. Any thoughts on implementing “infinite” scroll/zoom?

I’ve just finished implementing the infitine scroll for me.
In my Implementation I have UITableViewCell with a scrollView and Navigationbuttons. The scrollView contains x views all with the same width. views are alined horizontally and paging is enabled.

scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.showsHorizontalScrollIndicator = NO;

My codelogic is like the following:

  1. In my initialization function I
    • create all the views (for the scrollview) and
    • put them into an array and
    • add them to the scrollView
  2. Then I call a function that calculates in a loop the positions for each view (each time you detect a scroll this function will need to be called too). It always takes the first element of the array and sets the frame to (0,0,…,…), the second with (i*width,0,….,….) and so on. The function beeing called looks like this:

    - (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;
    }
    
  3. Then (still in the initialization process) I add an observer

    [scrollView addObserver:self forKeyPath:@"contentOffset" options:0 context:nil];
    

    so each time something in the scrollView changes I get the (observeValueForKeyPath)-function called, which looks like this:

    - (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];
            }
        }
    }
    
  4. And in dealloc or viewDidUnload (depends on how you implement it) don’t forget to remove the observer.

    [scrollView removeObserver:self forKeyPath:@"contentOffset"];   
    

Hope this helps, you might notice some overhead, but in my implementation I also support like scrolling 5 pages (well… unlimited) at once and autoanimated scrolling etc. so you might see something that could be thrown away.

Leave a Comment