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?
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.
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 */
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With