iOS自定义转场动画(2)——自定义Pop转场动画并加入手势驱动
来源:互联网 发布:php 抽象工厂模式 编辑:程序博客网 时间:2024/05/02 00:08
自定义Pop转场动画
继续使用上个程序,把push改为pop只需要做很少的工作就能完成
1、复制PushTransition.h和PushTransition.m。命名为PopTransition.h和PopTransition.m
2、在PopTransition.m中把
ViewController * fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];SecondViewController * toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
改为:
SecondViewController * fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];ViewController * toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
两个类名交换位置即可
3、把所有的avatarImageView改为sourceImageView,把所有的sourceImageView改为avatarImageView,如下:
// 转场动画的具体内容- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{ // 获取动画的源控制器和目标控制器 SecondViewController * fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; ViewController * toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; UIView * container = transitionContext.containerView; // 创建一个imageView的截图,并把原本imageView隐藏,造成以为移动的就是imageView的假象 UIView * snapshotView = [fromVC.avatarImageView snapshotViewAfterScreenUpdates:NO]; snapshotView.frame = [container convertRect:fromVC.avatarImageView.frame fromView:fromVC.view]; fromVC.avatarImageView.hidden = YES; // 设置目标控制器的位置,并把透明度设为0,在后面的动画中慢慢显示出来变为1 toVC.view.frame = [transitionContext finalFrameForViewController:toVC]; toVC.sourceImageView.hidden = YES; // 都添加到container中。注意顺序// [container addSubview:toVC.view]; [container insertSubview:toVC.view belowSubview:fromVC.view]; [container addSubview:snapshotView]; // 执行动画 [UIView animateKeyframesWithDuration:[self transitionDuration:transitionContext] delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{ snapshotView.frame = toVC.sourceImageView.frame; fromVC.view.alpha = 0; } completion:^(BOOL finished) { toVC.sourceImageView.hidden = NO; [snapshotView removeFromSuperview]; fromVC.avatarImageView.hidden = NO; //一定要记得动画完成后执行此方法,让系统管理 navigation [transitionContext completeTransition: ![transitionContext transitionWasCancelled]]; // 如果参数写成yes,当用户取消pop时,会继续执行动画,也就是让detailVC消失,设置成这个参数,会避免这样的错误 }];}
4、修改ViewController中的判断动画类型的方法,加入pop的判断:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{ if (operation == UINavigationControllerOperationPush){ // 就是在这里判断是哪种动画类型 return [[PushTransition alloc] init]; // 返回push动画的类 }else if (operation == UINavigationControllerOperationPop){ // 就是在这里判断是哪种动画类型 return [[PopTransition alloc] init]; // 返回pop动画的类{ }else{ return nil; }}
系统默认的 Push 和 Pop 动画都支持手势驱动,并且可以根据手势移动距离改变动画完成度。幸运的是,Cocoa 已经集成了相关方法,我们只用告诉它百分比就可以了。所以下一步就是 手势驱动。
1、在 SecondViewController 的 viewDidLoad() 方法中,加入滑动手势。
// 加入左侧边界手势 UIScreenEdgePanGestureRecognizer * edgePan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(edgePanGesture:)]; edgePan.edges = UIRectEdgeLeft; [self.view addGestureRecognizer:edgePan];
2、遵循UINavigationControllerDelegate协议,因为navigationController的动画需要在这里执行,所以需要设置代理为自己
- (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; self.navigationController.delegate = self;}
3、在手势监听方法中,创建 UIPercentDrivenInteractiveTransition 属性,并实现手势百分比更新。
// 在手势监听方法中,创建UIPercentDrivenInteractiveTransition属性,并实现手势百分比更新- (void)edgePanGesture:(UIScreenEdgePanGestureRecognizer *)edgePan{ // 进度值,这是左侧边界的算法,如果要改为右侧边界,改为self.view.bounds.size.width / [edgePan translationInView:self.view].x; CGFloat progress = [edgePan translationInView:self.view].x / self.view.bounds.size.width; if (edgePan.state == UIGestureRecognizerStateBegan) { self.percentDrivenTransition = [[UIPercentDrivenInteractiveTransition alloc] init]; [self.navigationController popViewControllerAnimated:YES]; }else if(edgePan.state == UIGestureRecognizerStateChanged){ [self.percentDrivenTransition updateInteractiveTransition:progress]; }else if(edgePan.state == UIGestureRecognizerStateCancelled || edgePan.state == UIGestureRecognizerStateEnded){ if(progress > 0.5){ [self.percentDrivenTransition finishInteractiveTransition]; }else{ [self.percentDrivenTransition cancelInteractiveTransition]; } self.percentDrivenTransition = nil; }}
4、实现返回 UIViewControllerInteractiveTransitioning 的方法并返回刚刚创建的 UIPercentDrivenInteractiveTransition属性。
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController{ if([animationController isKindOfClass:[PopTransition class]]){ return self.percentDrivenTransition; }else{ return nil; }}
5、还需要设置一下返回动画,否则手势驱动不会生效
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{ if (operation == UINavigationControllerOperationPop){ return [[PopTransition alloc] init]; // 返回pop动画的类 }else{ return nil; }}
完成
0 0
- iOS自定义转场动画(2)——自定义Pop转场动画并加入手势驱动
- 自定义转场动画 pop动画
- iOS开发之高级转场动画,tableview到collectionView自定义转场动画+手势驱动
- iOS自定义转场动画(4)——自定义模态跳转之dismiss与手势驱动
- iOS自定义转场动画
- iOS自定义转场动画
- IOS 自定义转场动画。
- iOS自定义转场动画
- iOS 自定义转场动画
- iOS自定义转场动画
- iOS - 自定义转场动画
- iOS自定义转场动画
- iOS自定义转场动画
- iOS自定义转场动画
- iOS自定义转场动画(1)——自定义Push转场动画
- iOS之转场动画/自定义转场动画
- iOS 自定义push转场动画
- iOS 自定义转场动画篇
- hdu 1686 Oulipo KMP 纯手搓
- 高通平台Camera框架部分浅谈--Camera C/S 的init流程
- [sicily]1052. Candy Sharing Game
- yii1框架寻找类的方法之import
- SpringMVC从Controller跳转到另一个Controller
- iOS自定义转场动画(2)——自定义Pop转场动画并加入手势驱动
- 从腾讯QQgame高性能服务器集群架构看“分而治之”与“自治”等分布式架构设计原则
- 《山海经——五藏山经》
- Ubuntu 手动安装firefox以及创建快捷方式和账号同步
- Java中Synchronized的用法
- JavaScript——js获取url方法,方便以后页面的跳转
- hdu2519 新生晚会
- Shiro使用和源码分析---1
- 从腾讯QQ升级游戏之“快速加入游戏”功能的实现缺陷看C/S之间如何正确分配相关协作