I have a custom UISplitViewController subclass in iOS 8. When in landscape I want the default behavior of both the primary and secondary VCs being visible (preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible
), but when I rotate to portrait I would like the primary VC to be displayed in the default popover (preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay
).
By implementing -viewWillTransitionToSize:
on the subclass I can kind of get this working, but after rotating a couple times the primary VC disappears and will not reappear until I tap the split view's bar button item.
The log in the rotation animation completion block on the first couple rotations shows the preferred display mode being the same as the actual display mode, but after a couple rotations the actual display mode is stuck as UISplitViewControllerDisplayModePrimaryOverlay
in landscape, even when the preferred display mode is UISplitViewControllerDisplayModeAllVisible
.
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
if (self.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
BOOL isPortrait = size.height > size.width;
if (isPortrait) {
self.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
}
else {
self.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
}
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
self.dividerView.hidden = isPortrait;
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
NSLog(@"Preferred display mode: %ld | Actual display mode: %ld", self.preferredDisplayMode, self.displayMode);
}];
}
}
Thanks to https://devforums.apple.com/message/1024928#1024928 I got it figured.
In the completion block for the animation coordinator, setting the preferredDisplayMode to UISplitViewControllerDisplayModeAutomatic makes it work.
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
if (self.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
BOOL isPortrait = size.height > size.width;
if (isPortrait) {
self.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
}
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (isPortrait) {
self.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
}
self.dividerView.hidden = isPortrait;
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// ADD THIS TO THE COMPLETION BLOCK
self.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic;
NSLog(@"Preferred display mode: %ld | Actual display mode: %ld", self.preferredDisplayMode, self.displayMode);
}];
}
}