1

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.

Fruity Geek
  • 7,351
  • 1
  • 32
  • 41

1 Answers1

2

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) {

                     }];
Fruity Geek
  • 7,351
  • 1
  • 32
  • 41
  • To get the current orientation you should use UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation] instead of [[UIDevice currentDevice] orientation] – ullstrm Nov 25 '13 at 15:08