I am playing around with the new UIViewControllerContextTransitioning
between UViewController
inside 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?
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.