2

I have a view controller that is using a custom transition, and it is working well. It takes advantage of the fact that when using UIModalPresentationCustom, the presenting view controller is not removed, and places the new view controller over it with transparency.

However, when using this in combination with state restoration, the presenting view controller IS removed. It would seem that because the view controller is presented without animations, the custom transition code is never called. Is there any way to have the custom transition activated, even when the view controller is not being animated?

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                  presentingController:(UIViewController *)presenting
                                                                      sourceController:(UIViewController *)source
{
    // never called if we aren't animating
    return self;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    return self;
}

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.25;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    if (toViewController == self) {
        [transitionContext.containerView addSubview:fromViewController.view];
        [transitionContext.containerView addSubview:toViewController.view];

        self.maskView.alpha = 0.0f;
        self.menuView.frame = CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, 286.0f);

        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;

            [self.menuView updateFrame:^(CGRect *frame) {
                frame->origin.y = self.view.bounds.size.height - frame->size.height;
            }];

            self.maskView.alpha = 0.75f;
        } completion:^(BOOL finished) {
            self.maskView.userInteractionEnabled = YES;
            [transitionContext completeTransition:YES];
        }];
    } else {
        [transitionContext.containerView addSubview:toViewController.view];
        [transitionContext.containerView addSubview:fromViewController.view];

        self.maskView.userInteractionEnabled = NO;

        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;

            [self.menuView updateFrame:^(CGRect *frame) {
                frame->origin.y = self.view.bounds.size.height;
            }];

            self.maskView.alpha = 0.0f;
        } completion:^(BOOL b){
            [transitionContext completeTransition:YES];

            [self.menuView updateFrame:^(CGRect *frame) {
                frame->origin.y = self.view.bounds.size.height - frame->size.height;
            }];
        }];
    }
}
David Beck
  • 10,099
  • 5
  • 51
  • 88

1 Answers1

0

I can't see how your presentingVC could be removed from hierarchy on state restoration, but what would helpful is to put the following in your app delegate:

- (UIViewController*)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder {
    NSLog(@"Application restore state = %@", [identifierComponents componentsJoinedByString:@"."]);

    return nil;
}

This way you can follow the state restoration logic if you do not implement custom state restoration classes and rely on Storyboard to do this for you. This may give a food for thoughts.

pronebird
  • 12,068
  • 5
  • 54
  • 82