11
votes

I'm making custom present and dismiss transitions and have some problems with it. What I want to do is repeat this cool deep animations in iOS 7 (when we open/close some app). I have First and Second Controllers. All animations are in First controller (it supports UIViewControllerTransitioningDelegate and UIViewControllerAnimatedTransitioning). So, I'm just checking: if it is presenting - I'm doing one animations (scaling up first and second view), if it is dismissing - I'm doing another animation (scaling down first and second view). Present animation works fine, the problem occurs with dismiss animation. In some reason when I'm scaling down my second controller (it is UINavigationController), I see black background behind it (and it's wrong, because I want to see my First controller while it's scaling down). Here is my code from First Controller

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIView *transitionView = [transitionContext containerView];

    id toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    id fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    BOOL isPresenting;

    isPresenting = [toViewController isKindOfClass:[UINavigationController class]];

    UINavigationController *navigator = isPresenting ? toViewController : fromViewController;

    if (isPresenting) {
        [transitionView addSubview:navigator.view];
        navigator.view.transform = CGAffineTransformMakeScale(0.1, 0.1);
        navigator.view.alpha = 0;
    }

    navigator.view.center = self.startButton.center;

    void(^AnimationBlock)(void) = ^ {
        if (isPresenting) {
            navigator.view.transform = CGAffineTransformMakeScale(1, 1);
            self.view.transform = CGAffineTransformMakeScale(4, 4);
            navigator.view.alpha = 1;
            self.startButton.alpha = 0;
        } else {
            navigator.view.transform = CGAffineTransformMakeScale(0.1, 0.1);
            self.view.transform = CGAffineTransformMakeScale(1, 1);
            navigator.view.alpha = 0;
            self.startButton.alpha = 1;
        }
    };

    [UIView animateWithDuration:1
                          delay:0.0f
         usingSpringWithDamping:50.0
          initialSpringVelocity:4
                        options:UIViewAnimationOptionLayoutSubviews
                     animations:^{
                         AnimationBlock();
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
        if (!isPresenting) {
            [navigator.view removeFromSuperview];
        }
    }];
}

- (void)completeTransitionInContext:(id<UIViewControllerContextTransitioning>)transitionContext{
    [transitionContext completeTransition:YES];
}


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


- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    return self;
}

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

Please tell me if I should to provide some additional code or screens. Thanks in advance!

3
iOS 7 API are still under NDA, until public availability (18 sept)Vinzzz
I have a very similar issue and iOS7 API is not under NDA any more... Could you please explain how to solve it? Thanks!veducm
Still don't know the answer :(Nastya Gorban

3 Answers

10
votes

You need to set modalPresentationStyle = UIModalPresentationCustom on the toVC before presenting it if you want to keep the fromVC in the window hierarchy after the present transition completes.

See my implementation of the sample code for WWDC Session 218: Custom Transitions Using View Controllers. If you click on 'Options' you'll see this type of transition. The relevant code is in SOLViewController.m prepareForSegue: and SOLOptionsTransitionAnimator.m

https://github.com/soleares/SOLPresentingFun

6
votes

When you present the custom VC, you should use: vc.modalPresentationStyle = UIModalPresentationCustom; but, if you typed wrong to vc.modalTransitionStyle = UIModalPresentationCustom; you will get a black background behind the custom VC.

3
votes

I think it is a good idea to use two separate AnimationController classes for Present and Dismiss animations and implement UIViewControllerTransitioningDelegate ( animationControllerForPresentedController and animationControllerForDismissedController ) inside your Parent ViewController.

To create an AnimationController just subclass NSObject and implement UIViewControllerAnimatedTransitioning there.

Hope it helps.