导航控制器过场动画的实现过程:
- 自定义导航控制器,并设置代理为设置self,实现
navigationController: animationControllerForOperation: fromViewController: toViewController:
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = self;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
AnimatedTransition1 *t1 = [[AnimatedTransition1 alloc] init];
t1.operation = operation;
return t1;
}
- 自定义
AnimatedTransition1 : NSObject<UIViewControllerAnimatedTransitioning>
。在navigationController: animationControllerForOperation: fromViewController: toViewController:
返回该类的对象。
// 指定动画时间
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 1;
}
// 动画怎么执行
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
// 执行动画所需的代码
}
过场动画上下文
UIViewControllerAnimatedTransitioning
协议中的代理方法- (void)animateTransition:
中有一个UIViewControllerContextTransitioning
类型的参数:transitionContext-过场动画上下文。
- 可获取控制器:fromVC、toVC
- 可获取视图:fromView、toView
- 可获取视图的初始化frame与最终frame:fromViewInitFrame、toViewInitFrame、fromViewFinalFrame、toViewFinalFrame
- containerView,并且containerView已经拥有fromView。toVC则需要手动添加。
下面提供一个实现动画的demo:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIView *containerView = transitionContext.containerView;
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
CGRect fromViewInitFrame = [transitionContext initialFrameForViewController:fromVC];
CGRect toViewInitFrame = [transitionContext initialFrameForViewController:fromVC];
CGRect fromViewFinalFrame = [transitionContext finalFrameForViewController:fromVC];
CGRect toViewFinalFrame = [transitionContext finalFrameForViewController:toVC];
[containerView addSubview:toView];
if (self.operation == UINavigationControllerOperationPush) {
fromViewInitFrame.origin.y = 0;
toViewInitFrame.origin.y = -fromViewInitFrame.size.height;
fromViewFinalFrame = fromViewInitFrame;
} else if (self.operation == UINavigationControllerOperationPop) {
fromViewInitFrame.origin.y = 0;
toViewInitFrame.origin.y = 0;
fromViewFinalFrame = fromViewInitFrame;
fromViewFinalFrame.origin.y = -fromViewInitFrame.size.height;
[containerView sendSubviewToBack:toView];
}
fromView.frame = fromViewInitFrame;
toView.frame = toViewInitFrame;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromView.frame = fromViewFinalFrame;
toView.frame = toViewFinalFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}