Edgar Edgar - 9 months ago 46
iOS Question

Custom transition for push animation with NavigationController on iOS 9

I have a custom push transition between view controllers embedded in a

which is working fine when built with iOS 7/8 but presents a wrong layout when built against iOS 9 SDK.

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

[transitionContext.containerView addSubview:toViewController.view];


It then goes on and performs an animation. The issue is that the content of the
, even though it is using the right top layout guide auto layout constraint, presents the content behind the navigation bar.

Nevertheless, it works fine on iOS 8 and if we force a redraw (e.g., sending the app to the background and bring it back, present a modal on top and dismiss it, etc) will cause the whole auto layout system to redraw itself and
's view jumps to the right place (as being the top layout guide, x pixels from the navigation bar rather than x pixels from the top of the device's screen).


[self.view setNeedsUpdateConstraints];
[self.view layoutIfNeeded];

Works if put in
, but does not work on
. This is not a solution as users would see the view jumping when the redraw is happening at


I've managed to fix my issue by adding the following line before addSubview::

  toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController];

From Apple's Documentation for finalFrameForViewController:

Returns the ending frame rectangle for the specified view controller’s view.

The rectangle returned by this method represents the size of the corresponding view at the end of the transition. For the view being covered during the presentation, the value returned by this method might be CGRectZero but it might also be a valid frame rectangle.