简体   繁体   中英

Custom Zoom Transition not working for a modal presentation

I am trying to create a Zoom Transition . I had it working totally fine when it was for a "push". Now I need to to work for a modal transition, and of course it can't just be a 2 min fix.

The transition is from one NavigationController to another. I still don't understand when the ViewController keys point to NavigationControllers , they should point to the actual ViewControllers ?

This does exactly what I want but viewWillAppear on the presented controller is NEVER called and the NavigationBar doesn't feel like appearing either.

Please help me. I would give every point I have to get this answered!

Here is the animation method:

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UINavigationController *fromNav = (id)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UINavigationController *toNav = (id)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    UIViewController<SWZoomTransitionDelegate> *fromVC= (UIViewController<SWZoomTransitionDelegate> *)fromNav.topViewController;
    UIViewController <SWZoomTransitionDelegate> *toVC =  (UIViewController<SWZoomTransitionDelegate> *)toNav.topViewController;

    UIView * containerView = [transitionContext containerView];
    UIView * fromView = [fromVC view];
    UIView * toView = [toVC view];

    [containerView addSubview:toView];

    UIView * zoomFromView = [fromVC viewForZoomTransition];
    UIView * zoomToView = [toVC viewForZoomTransition];

    UIImageView * animatingImageView = [self initialZoomSnapshotFromView:zoomFromView
                                                         destinationView:zoomToView];

    if ([fromVC respondsToSelector:@selector(initialZoomViewSnapshotFromProposedSnapshot:)])
    {
        animatingImageView = [fromVC initialZoomViewSnapshotFromProposedSnapshot:animatingImageView];
    }

    animatingImageView.frame = [zoomFromView.superview convertRect:zoomFromView.frame
                                                            toView:containerView];

    fromView.alpha = 1;
    toView.alpha = 0;
    zoomFromView.alpha = 0;
    zoomToView.alpha = 0;
    [containerView addSubview:animatingImageView];

    ZoomAnimationBlock animationBlock = nil;
    if ([fromVC respondsToSelector:@selector(animationBlockForZoomTransition)])
    {
        animationBlock = [fromVC animationBlockForZoomTransition];
    }

    [UIView animateKeyframesWithDuration:self.transitionDuration
                                   delay:0
                                 options:self.transitionAnimationOption
                              animations:^{
                                  animatingImageView.frame = [zoomToView.superview convertRect:zoomToView.frame toView:containerView];
                                  fromView.alpha = 0;
                                  toView.alpha = 1;

                                  if (animationBlock)
                                  {
                                      animationBlock(animatingImageView,zoomFromView,zoomToView);
                                  }
                              } completion:^(BOOL finished) {
                                  if ([transitionContext transitionWasCancelled]) {
                                      [toView removeFromSuperview];
                                      [transitionContext completeTransition:NO];
                                      zoomFromView.alpha = 1;
                                  } else {
                                      [fromView removeFromSuperview];
                                      [transitionContext completeTransition:YES];
                                      zoomToView.alpha = 1;
                                  }
                                  [animatingImageView removeFromSuperview];
                              }];
}

I had a similar issue with another project. Calling viewWillAppear: is definitely expected behavior, according to the WWDC session :

And so as an interactive transition starts, the machinery behind in UIKit is actually going to be making calls out to view will appear, view will disappear, will show view controller, all the stuff that you've normally used to kind of control what's happening in your application as things come on and off screen.

In my case, the issue was that the animator object was getting deallocated during the transition. I was setting up the animator like this:

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

    AGBAnimator *animator = [AGBAnimator new];
    return animator;
}

This object goes out of scope and is deallocated during the animation. By creating a strong property and assigning animator to it before returning from this method, the issue was resolved and viewWillAppear: , etc. was called successfully.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM