ContentOffset UIScrollView during rotation

I want to manually update the contentOffset UIScrollView during rotation changes. A scroll view fills the screen and has a flexible width and a flexible height.

I'm currently trying to update the contentOffset in willRotateToInterfaceOrientation , for example:

 - (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { [Utils logPoint:myScrollView.contentOffset tag:@"initial"]; myScrollView.contentOffset = CGPointMake(modifiedX, modifiedY); [Utils logPoint:myScrollView.contentOffset tag:@"modified"]; } -(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { [Utils logPoint:myScrollView.contentOffset tag:@"final"]; } 

However, the final value is not a modified value, and it seems to be affected by its influence, but this is not obvious to me.

Here are some of the results that I get:

 initial: (146.000000;-266.000000) modified: (81.000000;-108.000000) final: (59.000000;-0.000000) initial: (146.000000;-266.000000) modified: (500.000000;500.000000) final: (59.000000;500.000000) initial: (146.000000;-266.000000) modified: (-500.000000;-500.000000) final: (-0.000000;-0.000000) 

How to update contentOffset of scroll view during rotation change?

+6
iphone rotation ipad uiscrollview
source share
3 answers

Convert my comment to answer :)

Try replacing contentOffset with willAnimateRotationToInterfaceOrientation:duration: An animation block should be added at this point, and the OS considers your changes to contentOffset to be related to changes caused by rotation.

If you change the contentOffset before, it looks like the system does not consider these changes as belonging to the rotation, and it still applies the rotation size change, this time, starting with your new measurements.

+12
source share

The following snippets do the trick when paging is enabled in UIScrollView and page offset is supported.

Declare a property that will calculate the currentPage position before rotation and set the value -1 to viewDidLoad

 @property (assign, nonatomic) NSInteger lastPageBeforeRotate; 

Then override the willRotateToInterfaceOrientation:toInterfaceOrientation:duration method and assign it a value.

 - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { int pageWidth = self.scrollView.contentSize.width / self.images.count; int scrolledX = self.scrollView.contentOffset.x; self.lastPageBeforeRotate = 0; if (pageWidth > 0) { self.lastPageBeforeRotate = scrolledX / pageWidth; } [self showBackButton:NO]; } 

Then we guarantee that before the rotation is done, we will correctly set the scroll content offset to focus it on our lastPageBeforeRotate

 - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (self.lastPageBeforeRotate != -1) { self.scrollView.contentOffset = CGPointMake(self.scrollView.bounds.size.width * self.lastPageBeforeRotate, 0); self.lastPageBeforeRotate = -1; } } 
+4
source share

Updated answer for iOS 8+

Embed viewWillTransitionToSize: withTransitionCoordinator: in your controller.

Example:

 -(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { NSUInteger visiblePage = (NSInteger) self.scrollView.contentOffset.x / self.scrollView.bounds.size.width; [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { self.scrollView.contentOffset = CGPointMake(visiblePage * self.scrollView.bounds.size.width, self.scrollView.contentOffset.y); } completion:nil]; } 
+3
source share

All Articles