Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom transition animation not calling VC lifecycle methods on dismiss

Tags:

ios

ios7

So I built a custom presenting transition animation and everything seems to be working great except the view controller lifecycle methods are not being called on dismiss.

Before presenting the controller I use the UIModalPresentationCustom style to keep the presenting VC in the view hierarchy, but once I dismiss the presented VC, viewWillAppear and viewDidAppear are not called on my presenting controller. Am I missing a step that I need to explicitly call to get those methods to fire? I know manually calling those methods is not the correct solution.

Here is my dismissing animation code. I'm basically animating a form overlay view to shrink to the size of a collection view cell on dismissal.

- (void)_animateDismissingTransitionWithContext:(id<UIViewControllerContextTransitioning>)transitionContext {     UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];     UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];      UICollectionView *destinationCollectionView = toCollectionViewController.collectionView;     UICollectionViewCell *destinationCollectionViewCell = [self _destinationCellFromContext:transitionContext];     UIView *containerView = transitionContext.containerView;      // Calculate frames         CGRect startFrame = fromEventDetailViewController.detailContainerView.frame;     CGRect endFrame = [destinationCollectionView convertRect:destinationCollectionViewCell.frame toView:containerView];      // Add overlay     UIView *overlayView = [UIView new];     overlayView.backgroundColor = [UIColor overlayBackground];     overlayView.frame = containerView.bounds;     overlayView.alpha = 1.0f;     [containerView addSubview:overlayView];      // Add fake detail container view     UIView *fakeContainerView = [UIView new];     fakeContainerView.backgroundColor = fromEventDetailViewController.detailContainerView.backgroundColor;     fakeContainerView.frame = startFrame;     [containerView addSubview:fakeContainerView];      // Hide from view controller     fromEventDetailViewController.view.alpha = 0.0f;      [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:0.2f options:UIViewAnimationOptionCurveEaseOut animations:^{         fakeContainerView.frame = endFrame;         fakeContainerView.backgroundColor = [UIColor eventCellBackground];          overlayView.alpha = 0.0f;     } completion:^(BOOL finished) {         [fromEventDetailViewController.view removeFromSuperview];         [overlayView removeFromSuperview];         [fakeContainerView removeFromSuperview];          [transitionContext completeTransition:YES];     }]; } 
like image 536
Danny Avatar asked Aug 25 '14 14:08

Danny


People also ask

Do I need to call completetransition at the end of animations?

Calling the completeTransition: method at the end of your animations is required. UIKit does not end the transition process, and thereby return control to your app, until you call that method.

What is a transition animation?

A transition animation swaps the contents of one view controller for the contents of another. There are two types of transitions: presentations and dismissals. A presentation transition adds a new view controller to your app’s view controller hierarchy, whereas a dismissal transition removes one or more view controllers from the hierarchy.

How do I complete a transition animation in UIKit?

At the end of a transition animation, it is critical that you call the completeTransition: method. Calling that method tells UIKit that the transition is complete and that the user may begin to use the presented view controller.

When do transitions occur in a view controller?

Aside from the presentation and dismissal of a view controller, transitions can occur when an interface rotation occurs or when the frame of a view controller changes. All of these transitions represent changes to the view hierarchy.


1 Answers

Another solution could be using beginAppearanceTransition: and endAppearanceTransition:. According to documentation:

If you are implementing a custom container controller, use this method to tell the child that its views are about to appear or disappear. Do not invoke viewWillAppear:, viewWillDisappear:, viewDidAppear:, or viewDidDisappear: directly.

Here is how I used them:

- (void)animationEnded:(BOOL)transitionCompleted {     if (!transitionCompleted)     {         _toViewController.view.transform = CGAffineTransformIdentity;     }     else     {         [_toViewController endAppearanceTransition];     } }  - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {     UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];     UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];      [toViewController beginAppearanceTransition:YES animated:YES];     // ... other code } 

But I still consider strange that custom modal presentation not doing this.

like image 100
John Tracid Avatar answered Sep 27 '22 21:09

John Tracid