iosanimationios7uiviewcontrollercustom-transition

Ios 7 custom UINavigationController animation fails with mapView in destination controller


I am playing around with the new UIViewControllerContextTransitioning between UViewControllerinside UINavigationViewController

And what I have and what I want to achieve is quite simple but I fail somewhere

I have a MKMapView (300px * 60px) inside a UIScrollView. And from a click on that map (no matter where in the visible scroll it is) I want to segue over to next view that containts a fullsized MKMapView. The feeling and animation I am aiming for is for the user to feel they are being sucked into the map (kind of) =)

I have so far added: <UIViewControllerTransitioningDelegate, UINavigationControllerDelegate>

and

-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{

if (operation == UINavigationControllerOperationPush) {
    NSLog(@"inside itself");
    FixRTransitionAnimator *animator = [FixRTransitionAnimator new];
    animator.presenting = YES;
    CGRect absoluteframe = [self.mainScrollView convertRect:self.mapView.frame toView:self.view];
    animator.mapFrame = absoluteframe;
    NSLog(@"the map frame is %@", NSStringFromCGRect(self.mapView.frame));
    return animator;
}
else
    NSLog(@"nope its outside");
return nil;
}

And to the prepareForSegue method I have:

   [super prepareForSegue:sender sender:sender];

    MapViewController *mapViewController = segue.destinationViewController;
    mapViewController.transitioningDelegate = self;
    mapViewController.modalPresentationStyle = UIModalPresentationCustom;

And finally I have the `FixRTransitionAnimator.m``

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
NSLog(@"the time is timed");
return 0.5f;
}
 -(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
NSLog(@"we are inside %@",NSStringFromCGRect(self.mapFrame));
UIViewController *fromVController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

CGRect endFrame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width,[UIScreen mainScreen].bounds.size.height);

if (self.presenting) {
    fromVController.view.userInteractionEnabled = NO;

    [[transitionContext containerView]addSubview:fromVController.view];
    [[transitionContext containerView]addSubview:toVController.view];

    toVController.view.frame = self.mapFrame;


     [UIView animateWithDuration:[self transitionDuration:transitionContext]      animations:^{
        fromVController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
        NSLog(@"inside the animation");
        toVController.view.frame = endFrame;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}else{
   ...
}

}

The transition animation works nice and fine with the destinationViewController empty. But with the map inside the animation works really weird and not at all as I wanted.

Any1 got any pointers to what I miss or need to think of?


Solution

  • I wrote a post in another answer, but make sure you are setting your UINavigationControllerDelegate.

    There is a UIViewControllerTransitioningDelegate for presented controllers, and a UINavigationControllerDelegate for pushed controllers. The delegate methods inside the protocols return your animator.