When I rotate my view controller on an iPad 8.4, my view doesn't extend all the way to the right:
In this example, the red view is my root view controller, and it should never be visible. I embed a navigation controller using UIViewController containment, and that should fill up the entire screen and cover the red portion.
Why is it causing this behavior, and how can I resolve it?
If I try running it on an iPhone, or iOS 9, it is fixed.
I was able to reproduce the problem with a minimum amount of steps:
Steps to reproduce problem (or try this GitHub project):
- Create a new project in Xcode 7.
- Change the target to iOS 8.4.
- Delete your view controller's view in the storyboard, and then re-add it.
- Change the view controller's background color so we can see what is going on.
- Embed the view controller in a navigation controller.
- Add a navigation item to the view controller.
- Add a center navigation item view by dragging in a UIView to the storyboard.
- Add a second view as a subview of the one that was just created.
- Add a new view controller to the storyboard and set it as the initial view controller.
- In the new view controller's view did load method, embed the navigation controller using auto layout.
- Run on an iPad Air (8.4) in portrait.
- Rotate the iPad to the right so that it is in landscape.
- Notice how the red portion sticks out of the view.
Things that fix it:
- Use iOS 9.0
- Use an iPhone instead of an iPad
- Don't have two views in the navigation item's center position (a single view is fine; but a label inside of a view, for example, will cause this sort of breakage).
- Open up the XML for the storyboard and change the view controller's view's
autoresizingMask
from <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
to <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
. (By default when you drag in a view controller to the storyboard, it will use the ...Sizable
variants. If, however, you delete the view (not the view controller), then drag a view back into the view controller, it will use the flexibleMax...
variants.)
- Don't use UIViewController containment.
- If you do use UIViewController containment, let the storyboard embed the view controller.
- If you do use UIViewController containment programmatically, then ensure that
translatesAutoresizingMaskIntoConstraints
is set to YES
rather than NO
. If you compare the auto layout way of embedding a view controller vs. the storyboard way of embedding a view controller, you will see that the storyboard sets translatesAutoresizingMaskIntoConstraints=YES
, therefore, instead of trying to set up constraints, simply keep translatesAutoresizingMaskIntoConstraints set to YES, and set the childView.frame = parentView.bounds
, to mimic the storyboard embedding behavior. (Note, you can also see that by default the storyboard will have the embedded view's autoresize
set to W+H
, so you should ensure that your view has that set.)