Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite Scrolling - setContentOffset: stops deceleration of UIScrollView

I am creating an iPhone app with a large, 360 degree, panorama image. The panorama is a CATiledLayer in a UIScrollView.

I am attempting to implement infinite scrolling on the image (horizontal only). I have done this by subclassing UIScrollView and implementing setContentOffset: and setContentOffset:animated: and this works perfectly when the user is dragging the scrollview. However, when the user has lifted their finger and the scrollview is decelerating, changing the contentOffset causes the deceleration to stop instantly.

- (void)setContentOffset:(CGPoint)contentOffset 
{    
    CGPoint tempContentOffset = contentOffset;

    if ((int)tempContentOffset.x >= 5114)
    {
        tempContentOffset = CGPointMake(1, tempContentOffset.y);
    }
    else if ((int)tempContentOffset.x <= 0)
    {
        tempContentOffset = CGPointMake(5113, tempContentOffset.y);
    }

    [super setContentOffset:tempContentOffset];    
}

Is there any way to change the contentOffset without affecting deceleration?

It was suggested here that overriding setContentOffset: (not setContentOffset:animated:) fixes this issue, but I can't seem to get it working.

I have also tried scrollRectToVisible:animated: with no success.

Any ideas on how to fix this problem would be greatly appreciated. Thanks!

EDIT:

Code for scrollViewDidScroll:

-(void)scrollViewDidScroll:(PanoramaScrollView *)scrollView
{
    [panoramaScrollView setContentOffset:panoramaScrollView.contentOffset];
}   

I also tried this:

-(void)scrollViewDidScroll:(PanoramaScrollView *)scrollView
{
    CGPoint tempContentOffset = panoramaScrollView.contentOffset;

    if ((int)tempContentOffset.x >= 5114)
    {
        panoramaScrollView.contentOffset = CGPointMake(1, panoramaScrollView.contentOffset.y);
    }
    else if ((int)tempContentOffset.x == 0)
    {
        panoramaScrollView.contentOffset = CGPointMake(5113, panoramaScrollView.contentOffset.y);
    }
}
like image 587
Steph Sharp Avatar asked May 01 '12 11:05

Steph Sharp


3 Answers

Instead of

[scrollView setContentOffset:tempContentOffset];

use

scrollView.contentOffset = tempContentOffset;
like image 172
david72 Avatar answered Nov 18 '22 02:11

david72


I resolved the issue with a workaround. I created a panorama image with 3 full widths of the panorama (doesnt affect performance too much because I'm using CATiledLayer), and set the decelerationRate property to UIScrollViewDecelerationFast. Therefore, the user is unable to scroll too far before the deceleration stops, and if the deceleration stops in either the left or right panorama image, the content offset is then changed back to the middle image. This has the appearance of infinite scrolling, and it's the best solution I could come up with.

like image 32
Steph Sharp Avatar answered Nov 18 '22 03:11

Steph Sharp


I recently was doing the same infinite scrolling and accidentally found the solution:

Just set bounces=YES, alwaysBounceHorizontal=YES or/and alwaysBounceVertical=YES (depends on direction you scrolling to).

That's it, this works for me. :)

like image 1
krafter Avatar answered Nov 18 '22 03:11

krafter