1.控制器跳转时,实现UIViewControllerTransitioningDelegate代理。服务于进入时动画和返回时动画效果。
TestViewController *tableview = [TestViewController new];
tableview.transitioningDelegate = self;
[self presentViewController:tableview animated:YES completion:nil];
2.实现代理方法
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
AnimationController *animation = [AnimationController new];//动画效果
animation.reverse = NO;//进栈时标识
return animation;
}
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
AnimationController *animation = [AnimationController new];
animation.reverse = YES;//出栈时标识
return animation;
}
3.动画效果的实现AnimationController,实现UIViewControllerAnimatedTransitioning协议规范(建议按照规范来)。
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return self.duration;//动画时长
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
//实现从上出现,从当前位置到上面的消失效果。
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = toVC.view;
UIView *fromView = fromVC.view;
UIView *containerView = [transitionContext containerView];
[containerView addSubview:toView];
if (self.reverse) {//消失时处理
fromView.frame = CGRectMake(fromView.frame.origin.x, fromView.frame.origin.x, fromView.frame.size.width, fromView.frame.size.height);
} else {//出现时处理初始位置
toView.frame = CGRectMake(toView.frame.origin.x, -1*toView.frame.size.height, toView.frame.size.width, toView.frame.size.height);
}
self.reverse ? [containerView sendSubviewToBack:toView] : [containerView bringSubviewToFront:toView];
// animate
NSTimeInterval duration = [self transitionDuration:transitionContext];
[UIView animateWithDuration:duration animations:^{
if (self.reverse) {
fromView.frame = CGRectMake(fromView.frame.origin.x, -1 * fromView.frame.size.height, fromView.frame.size.width, fromView.frame.size.height);
} else {
toView.frame = CGRectMake(toView.frame.origin.x, 0, toView.frame.size.width, toView.frame.size.height);
}
} completion:^(BOOL finished) {
if ([transitionContext transitionWasCancelled]) {
toView.frame = CGRectMake(0, toView.frame.origin.y, toView.frame.size.width, toView.frame.size.height);
fromView.frame = CGRectMake(0, fromView.frame.origin.y, fromView.frame.size.width, fromView.frame.size.height);
} else {
[fromView removeFromSuperview];
}
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}