In my UISplitViewController, I want the master view controller to only be allowed to display when in Portrait orientation or when my detail view controller is not displaying a type of controller, MyFullScreenViewController
. I've implemented the UISplitViewControllerDelegate to indicate this appropriately.
-(BOOL)splitViewController:(UISplitViewController *)svc
shouldHideViewController:(UIViewController *)vc
inOrientation:(UIInterfaceOrientation)orientation
{
if (UIInterfaceOrientationIsPortrait(orientation) ||
[[self.navigationController topViewController] isKindOfClass:[MyFullScreenViewController class]])
{
return YES;
}
return NO;
}
However, the UISplitViewController only invokes the delegate during rotation. So MyFullScreenViewController
implements a viewWillAppear:animated
and viewWillDisappear:animated
.
- (void)viewWillAppear:(BOOL)animated
{
[self fakeRotationOfSplitViewController];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self fakeRotationOfSplitViewController];
[super viewWillDisappear:animated];
}
-(void)fakeRotationOfSplitViewController
{
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
CGFloat duration = 1.0f;
CGFloat fakeDuration = 0.0f;
[UIView animateWithDuration:duration
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[[self splitViewController] willAnimateRotationToInterfaceOrientation:orientation
duration:fakeDuration];
[[self splitViewController] willRotateToInterfaceOrientation:orientation
duration:fakeDuration];
[[self splitViewController] didRotateFromInterfaceOrientation:orientation];
} completion:^(BOOL finished) {
}];
}
Everything works except the animation. The master view controller immediately disappears and reappears prior to the UINavigationController
object's push and prior to the pop animation.
The documentation is unclear whether willRotateToInterfaceOrientation:duration:
and didRotateFromInterfaceOrientation:
should be called within the animation block, but I suspect they shouldn't to allow the view controller to animate it changes in response to the message. However if they fall outside the animation block, the master view controller will sometimes disappear.
The animation was not working because I never called viewWillLayoutSubviews
after didRotateFromInterfaceOrientation:
.
[UIView animateWithDuration:duration
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[[self splitViewController] willAnimateRotationToInterfaceOrientation:orientation
duration:fakeDuration];
[[self splitViewController] willRotateToInterfaceOrientation:orientation
duration:fakeDuration];
[[self splitViewController] didRotateFromInterfaceOrientation:orientation];
[[self splitViewController] viewWillLayoutSubviews];
[[[self splitViewController] view] layoutSubviews];
} completion:^(BOOL finished) {
}];