Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIPageViewController + Auto Layout rotation issue

I have a UIPageViewController with a simple UIViewController inside of it.

If the the UIViewController has no subviews, its view resizes correctly when rotated. (Solid green background).

portraitlandscape

If the the UIViewController has a subview with a fixed frame, its view resizes correctly when rotated. (Solid green background with yellow square in corner).

portraitlandscape

If the the UIViewController has a subview with its auto layout constraints set to fill its superview, its view no longer resizes correctly when rotated. (Solid yellow background with the UIPageViewController's red background visible). The auto layout code I use is:

UIView *v = [[UIView alloc] init];
[v setTranslatesAutoresizingMaskIntoConstraints:NO];
[v setBackgroundColor:[UIColor yellowColor]];
[[self view] addSubview:v];

NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(v);

NSArray *cs = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[v]|" options:0 metrics:nil views:viewsDictionary];
[[self view] addConstraints:cs];

cs = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[v]|" options:0 metrics:nil views:viewsDictionary];
[[self view] addConstraints:cs];

portraitlandscape

Why would the auto layout of a subview affect its superview? This only happens if it is contained within a UIPageViewController.

like image 599
Senior Avatar asked Jul 18 '13 16:07

Senior


2 Answers

I had this problem too and the previous answers didn't seem to help much. I needed to add constraints to the scrollview used with the PageViewController.

// Add Paging View Controller
self.addChildViewController(self.pageViewController)
self.pageViewController.didMoveToParentViewController(self)
self.containerView.addSubview(self.pageViewController.view)

// Add Constraints
var verticalConstraints:Array = NSLayoutConstraint.constraintsWithVisualFormat("V:|[View]|", options: nil, metrics: nil, views: ["View":self.pageViewController.view])
var horizontalConstraints:Array = NSLayoutConstraint.constraintsWithVisualFormat("|[View]|", options: nil, metrics: nil, views: ["View":self.pageViewController.view])

self.pageViewController.view.setTranslatesAutoresizingMaskIntoConstraints(false)
self.containerView.addConstraints(verticalConstraints)
self.containerView.addConstraints(horizontalConstraints)

// Add Constraints for the Scrollview
//This line is a bit of a hack.  If Apple ever changes the structure of the UIPageViewController, this could break.
let scrollView = self.pageViewController.view.subviews.first! as UIView  
scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("V:|[View]|", options: nil, metrics: nil, views: ["View":scrollView])
horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("|[View]|", options: nil, metrics: nil, views: ["View":scrollView])
self.pageViewController.view.addConstraints(verticalConstraints)
self.pageViewController.view.addConstraints(horizontalConstraints)
like image 61
Barlow Tucker Avatar answered Oct 18 '22 21:10

Barlow Tucker


The page view controller's view is not the superview of the views that represent the pages. The page view controller's view has a view hierarchy consisting of a custom scroll view subclass, and that scroll view in turn has three generic view subclasses, one each for the views of contained view controllers at indices 0 through 2. Those serve as the superviews for your contained views. You would have to target your auto layout constraints to those views. But it's much easier to use the autoresizing masks and let them get converted to auto layout constraints.

like image 45
Bored Astronaut Avatar answered Oct 18 '22 20:10

Bored Astronaut