Autolayout changes UIScrollView contentOffset when rotating

To experiment with autolayout and uiscrollview, I used this example

which I edited to include 2 views in the scroll view, I set auto-detection restrictions to arrange the horizontal views with their size set to fill the scroll frame.

UIView *beeView = [[[NSBundle mainBundle] loadNibNamed:@"BeeView" owner:nil options:nil] firstObject]; beeView.translatesAutoresizingMaskIntoConstraints = NO; [self.scrollView addSubview:beeView]; UIView *beeView2 = [[[NSBundle mainBundle] loadNibNamed:@"BeeView" owner:nil options:nil] firstObject]; beeView2.backgroundColor= [UIColor orangeColor]; beeView2.translatesAutoresizingMaskIntoConstraints = NO; [self.scrollView addSubview:beeView2]; NSDictionary *views = @{@"beeView":beeView,@"beeView2":beeView2, @"scrollView":self.scrollView}; NSDictionary *metrics = @{@"height" : @200}; [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[beeView(==scrollView)][beeView2(==beeView)]|" options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metrics views:views]]; [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[beeView(==scrollView)]|" options:kNilOptions metrics:metrics views:views]]; 

which beautifully creates what I intended.

However, if the scroll view of the contentOffset is non-zero, and the device rotates from portrait to landscape, the scroll content offset is automatically set to 32px . (see screenshot) incorrect content offset

I tried to save the contentOffset and set it for this saved value when scrollViewDidEndDecelerating: is scrollViewDidEndDecelerating: , which works, but is ugly when the scroll scrolls to an offset of 32 pixels and then back to where I want.

How to control scroll view contentOffset ? Are auto-detection restrictions wrong? Are there any additional restrictions that I can add to control the contentOffset when resizing a view?

+6
source share
3 answers

Where does 32px come from? Is this related to your left and right scrollView margin?

Does the error persist with every page change? In this case, you should look at your scrollView contentInsets.

Otherwise, what I am doing to control the rotation on a scrollView with paging is to view the scrollView contentSize:

First, when you load the view, add an observer:

 [self.scrollView addObserver:self forKeyPath:NSStringFromSelector(@selector(contentSize)) options:0 context:nil]; 

Then, when the contentSize value changes, configure contentOffset:

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == self.scrollView && [keyPath isEqualToString:NSStringFromSelector(@selector(contentSize))]) { //Note that you should track your page index self.scrollView.contentOffset = CGPointMake(self.pageIndex * self.scrollView.bounds.size.width, self.scrollView.contentOffset.y); } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } 

Finally, remove the observer when unloading scrollView:

 [self.scrollView removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentSize)) context:nil]; 
+8
source

Let's go back to a few previous posts: one and two . It seems you can find your solution by doing one of the following steps:

  • Programmatically : if the parent VC of your UIScrollViews is not directly on the Nav stack -

~ Change ~

  // Without a Navigation Controller self.automaticallyAdjustsScrollViewInsets = NO; // With a Navigation Controller self.parentViewController.automaticallyAdjustsScrollViewInsets = NO; self.automaticallyAdjustsScrollViewInsets = NO; 
  1. Interface Designer : Attribute Inspector โ†’ Uncheck the Configure scroll inserts in layout properties check box.

  2. IF Still Unsuccessful . In the presented ViewWillLayoutSubviews view controller, try setting each of the following UIScrollView properties:

     self.scrollView.contentOffset = CGPointZero; self.scrollView.contentInset = UIEdgeInsetsZero; 

I assume that the combination of options 1 and 2 will work depending on how your navigation stack is structured.

+3
source

I know this is an old question, but if it is used by anyone, I created a subclass of UIScrollView called LMPageView , which automatically applies the necessary layout constraints and corrects the offset content when rotating. The class is available as part of the MarkupKit project on GitHub. Usage Example (Swift):

 // Add 3 page views pageView.addPage(view1) pageView.addPage(view2) pageView.addPage(view3) // Show the 3rd page pageView.currentPage = 2 

An additional example that uses markup to initialize pageviews can be found here:

0
source

All Articles