Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIScrollView disable scrolling while rotating on iPhone/iPad

Tags:

I am using UIScrollView and an image in it as paging one image per page. I have a problem while rotating the iPhone

When I rotate the iPhone then scrollViewDidScroll (Scroll view delegate method) is calling. Due to this, my paging is disturbed and the page number changes.

What is the solution?

like image 342
Amit Battan Avatar asked Nov 08 '10 12:11

Amit Battan


2 Answers

I found a strange undocumented behavior when rotating a paged UIScrollView.

When the scrollview is positioned at the last page and the user changes the orientation, the OS scrolls the UIScrollView a few pixels back to compensate for the difference between height and width.

Basically I received the following calls for any page.

willRotateToInterfaceOrientation:duration
willAnimateRotationToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:

And for the last page:

willRotateToInterfaceOrientation:duration
scrollViewDidScroll:
willAnimateRotationToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:

That messed up with my pages too. The problem is that in willRotate, the bounds have not been updated by the OS yet, and in willAnimate you have the new bounds and can compute the new size, but it's too late...

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    CGSize tempSize = [self.pagingScrollView contentSize];
    NSUInteger padding = abs(pagingScrollView.frame.size.width - pagingScrollView.frame.size.height);
    tempSize.width += padding;
    [self.pagingScrollView setContentSize:tempSize];
    [...]
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration{
    CGSize newSize = ... // Compute new content size based on new orientation
    [self.pagingScrollView setContentSize:newSize];
}

This is just a workaround, but I spent countless hours on this issue and could not find an elegant solution.

like image 27
Raphaël Mor Avatar answered Sep 19 '22 15:09

Raphaël Mor


Raphaël's answer is an excellent description of the problem, and a neat fix. I had the exact same problem and ended up fixing with a scrollingLocked flag that I set to YES (locked) before the rotation starts, and NO (unlocked) when it ends. Perhaps slightly less hacky than temporarily changing the contentSize:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
                                duration:(NSTimeInterval)duration
{
    self.photoViewer.scrollingLocked = YES;
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation
{
    self.photoViewer.scrollingLocked = NO;
}

- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
    if (self.scrollingLocked)
    {
        return;
    }
    /* do normal scrollViewDidScroll: stuff */
}
like image 94
Ben Hoyt Avatar answered Sep 19 '22 15:09

Ben Hoyt