先看效果
项目中有要求要用一个切换特效,研究了下发现是拿转场动画做的,所以把之前的知识重新复习下,这里提供一个简单的思路实现转场动画,具体的效果大概是跳转的新的控制器页面从左上角开始向右边拉伸到充满屏幕,同时底部有一个view弹上来.
我想创建两个控制器,当前控制器是GHTransitionAnimationViewController 目标控制器是GHTransitionAnimationToViewController
在GHTransitionAnimationViewController 需要设置navigationController.delegate,遵守协议UINavigationControllerDelegate
然后新建一个继承自NSObejct的GHTransitionAnimation类,这个类需要遵守协议UIViewControllerAnimatedTransitioning 同时必须实现两个代理方法
这个代理方法是返回的动画持续时间, NSTimeInterval类型
- (NSTimeInterval)transitionDuration:(id )transitionContext{ }
方法是转场动画的核心方法,所有的动画需要在这个方法里去写
- (void)animateTransition:(id )transitionContext { }
transitionContext是转场上下文,提供转场动画的所有细节,在上下文我们可以拿到原控制器和目标控制器
- (void)animateTransition:(id )transitionContext{ /** 目标控制器 */ UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; /** 原控制器 */ UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIView *toView = nil; UIView *fromView = nil; if ([transitionContext respondsToSelector:@selector(viewForKey:)]) { fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]; toView = [transitionContext viewForKey:UITransitionContextToViewKey]; } else { fromView = fromViewController.view; toView = toViewController.view; } /** containView */ UIView *containView = [transitionContext containerView]; [containView addSubview:toView]; UIImageView *imageView = [toView subviews].firstObject; imageView.frame = CGRectMake(0, 64, 0, 0); UIView *view = [toView subviews].lastObject; view.frame = CGRectMake(0, kScreenHeight - 64, kScreenWidth, 50); CGFloat width = [UIScreen mainScreen].bounds.size.width; CGFloat height = [UIScreen mainScreen].bounds.size.height; [containView addSubview:imageView]; toView.frame = CGRectMake(0, 64, 0, 0); [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ // view.frame = CGRectMake(0, kScreenHeight - 50 - 64, kScreenWidth, 50); toView.frame = CGRectMake(0, 64, width, height); imageView.frame = CGRectMake(0, 64, kScreenWidth, 220); view.frame = CGRectMake(0, kScreenHeight - 50 - 64, kScreenWidth, 50); } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; }
GHTransitionAnimationToViewController 里创建两个view
GHImageView *imageView = [[GHImageView alloc]init]; imageView.image = [UIImage imageNamed:@"jingtian1"]; imageView.frame = CGRectMake(0, 64, kScreenWidth, 220); imageView.tag = 10; [self.view addSubview:imageView]; self.view.backgroundColor = [UIColor redColor]; GHView *bottomView = [[GHView alloc]init]; bottomView.frame = CGRectMake(0, kScreenHeight - 50 - 64, kScreenWidth, 50); bottomView.backgroundColor = [UIColor orangeColor]; bottomView.tag = 10; [self.view addSubview:bottomView];
最后要调用方法,在原控制器里添加自定义的类
- (id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{ if (operation == UINavigationControllerOperationPush) { return [[GHTransitionAnimation alloc] init]; } return nil; }
说明: [transitionContext completeTransition:YES];这个方法是告诉控制器转场动画完成,在结束动画一定要写,然后控制器认为动画没有结束,所有的控件没有交互效果.