IOS7的转场动画和CATransform3D简单使用
来源:互联网 发布:丝绒窗帘知乎 编辑:程序博客网 时间:2024/05/22 13:32
说来惭愧自己惭愧,由于自己开启了懒汉模式,一直没怎么研究过IOS7新的转场的动画,今天死磕的一天终于有点成效,还简单弄了下CATransform3D的内容
先看图
现在好多APP喜欢这样玩转场动画。。。于是就简单研究了一下 ,适合初学者,没有过多介绍深层的东西
说白了这就是执行了present的跳转代码
SecViewController *sec = [[SecViewController alloc]init]; sec.transitioningDelegate = self; //让动画变得炫酷就靠它了 [self presentViewController:sec animated:YES completion:nil];
是不是就多了实现了一个代理?没错,靠它 我们就能实现这样的炫酷动画了。
这个代理里需要实现两个方法
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { _presentAnimation.duration = 1; self.presentAnimation.reverse = NO; return self.presentAnimation;}- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { self.presentAnimation.reverse = YES; return self.presentAnimation;}
这两个带来方法从方法名称基本就明白什么意思啦?一个是present的实现方法,一个是dismiss的实现方法。
这里面返回的是什么呢?这里就是我们返回的自定义动画
下面说说这个自定义动画的类的构造吧
接口文件
/** * 自定义的动画类 * 实现协议------>@protocol UIViewControllerAnimatedTransitioning * 这个接口负责切换的具体内容,也即“切换中应该发生什么” */#import <Foundation/Foundation.h>@interface CustomAnimatior : NSObject<UIViewControllerAnimatedTransitioning>@property (nonatomic, assign) NSTimeInterval duration;//执行时间@property (nonatomic, assign) BOOL reverse;//执行present或者dismiss的标识@end
实现文件
#import <UIKit/UIKit.h>#import "CustomAnimatior.h"@interface CustomAnimatior()@end@implementation CustomAnimatior// 系统给出一个切换上下文,我们根据上下文环境返回这个切换所需要的花费时间- (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; [self animateTransition:transitionContext fromVC:fromVC toVC:toVC fromView:fromView toView:toView];}// 完成容器转场动画的主要方法,我们对于切换时的UIView的设置和动画都在这个方法中完成- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView { if(self.reverse){ [self executeReverseAnimation:transitionContext fromVC:fromVC toVC:toVC fromView:fromView toView:toView]; } else { [self executeForwardsAnimation:transitionContext fromVC:fromVC toVC:toVC fromView:fromView toView:toView]; }}-(void)executeReverseAnimation:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView { UIView* containerView = [transitionContext containerView]; // positions the to- view behind the from- view CGRect frame = [transitionContext initialFrameForViewController:fromVC]; toView.frame = frame; CATransform3D scale = CATransform3DIdentity; toView.layer.transform = CATransform3DScale(scale, 0.6, 0.6, 1); toView.alpha = 0.6; [containerView insertSubview:toView belowSubview:fromView]; CGRect frameOffScreen = frame; frameOffScreen.origin.y = frame.size.height; CATransform3D t1 = [self firstTransform]; [UIView animateKeyframesWithDuration:self.duration delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{ // push the from- view off the bottom of the screen [UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:0.5f animations:^{ fromView.frame = frameOffScreen; }]; // animate the to- view into place [UIView addKeyframeWithRelativeStartTime:0.35f relativeDuration:0.35f animations:^{ toView.layer.transform = t1; toView.alpha = 1.0; }]; [UIView addKeyframeWithRelativeStartTime:0.75f relativeDuration:0.25f animations:^{ toView.layer.transform = CATransform3DIdentity; }]; } completion:^(BOOL finished) { if ([transitionContext transitionWasCancelled]) { toView.layer.transform = CATransform3DIdentity; toView.alpha = 1.0; } [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }];}-(void)executeForwardsAnimation:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView { UIView* containerView = [transitionContext containerView]; // positions the to- view off the bottom of the sceen CGRect frame = [transitionContext initialFrameForViewController:fromVC]; CGRect offScreenFrame = frame; offScreenFrame.origin.y = offScreenFrame.size.height; toView.frame = offScreenFrame; [containerView insertSubview:toView aboveSubview:fromView]; CATransform3D t1 = [self firstTransform]; CATransform3D t2 = [self secondTransformWithView:fromView]; [UIView animateKeyframesWithDuration:self.duration delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{ //这里用到的是关键帧动画,也是iOS7的新特性 // push the from- view to the back [UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:0.4f animations:^{ fromView.layer.transform = t1; fromView.alpha = 0.6; }]; [UIView addKeyframeWithRelativeStartTime:0.2f relativeDuration:0.4f animations:^{ fromView.layer.transform = t2; }]; // slide the to- view upwards. In his original implementation Tope used a 'spring' animation, however // this does not work with keyframes, so we siulate it by overshooting the final location in // the first keyframe [UIView addKeyframeWithRelativeStartTime:0.6f relativeDuration:0.2f animations:^{ toView.frame = CGRectOffset(toView.frame, 0.0, -30.0); }]; [UIView addKeyframeWithRelativeStartTime:0.8f relativeDuration:0.2f animations:^{ toView.frame = frame; }]; } completion:^(BOOL finished) { [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; }-(CATransform3D)firstTransform{ CATransform3D t1 = CATransform3DIdentity; t1.m34 = 1.0/-500; //应该透视参数 ,这个值应该是和rotation所匹配的 ,这个值越小 透视角度越大 正负代表透视方向 t1 = CATransform3DScale(t1, 0.95, 0.95, 1);//这个3D的缩放,x,y,z t1 = CATransform3DRotate(t1, 15.0f * M_PI/180.0f, 1, 0, 0); return t1; }-(CATransform3D)secondTransformWithView:(UIView*)view{ CATransform3D t2 = CATransform3DIdentity; t2.m34 = [self firstTransform].m34; //这是视图的偏移量 tx:X轴偏移位置,往右为正数。 ty:Y轴偏移位置,往下为正数。 tz:Z轴偏移位置,往外为正数。 t2 = CATransform3DTranslate(t2, 0, view.frame.size.height*-0.08, 0); t2 = CATransform3DScale(t2, 0.8, 0.8, 1); return t2;}
在这个文件里需要引入
UIViewControllerAnimatedTransitioning的代理
并且实现两个方法
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
<pre name="code" class="objc">- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
transitionContext第一个方法是返回的时间 ,第二个就是方法就是我们需要自己自定义的动画。通过transitionContext可以获取到 当下的容器view
[transitionContext containerView]以及formView和toView 这两个顾名思义 一个是当前的view 一个是切换的view。
viewControllerForKey:UITransitionContextFromViewControllerKey和
viewControllerForKey:UITransitionContextToViewControllerKey两个方法获取。
在创建动画的时候还用到了一个有关动画的特性就是关键帧动画
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
这个是穿件关键帧动画的方法
下面的是穿件单个帧动画的方法
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0);
CATransform3D在实现上也没有什么难度.m文件里已经有了注释,靠自己的理解 ,可能有些3D参数理解有误,发现错误请评论谢谢
创建好这个类然后在ViewController实例化
@property (nonatomic, strong)CustomAnimatior *p
_presentAnimation = [CustomAnimatior new];
一定要实例化。。。
各位没玩过码友,赶紧试试吧
源码下载地址:
https://coding.net/u/alexgaoCode/p/IOS-translationDEMO/git
0 0
- IOS7的转场动画和CATransform3D简单使用
- CATransition(转场动画)的简单使用
- iOS7使用代理自定义导航转场动画
- CATransition 简单使用(转场动画)
- iOS那些简单的动画,属性详解和转场动画
- 自定义简单的转场动画
- 转场动画的基本使用
- ios7 push/pop转场动画
- UITableViewCell 的CATransform3D动画
- 自己动手编写一些简单的转场动画
- CABasicAnimation动画、动画组 与简单的转场动画CATransition
- Swift3.0转场动画的使用
- Android 5.0 转场动画的使用
- iOS7中ViewControllers之间自定义转场动画
- Android Activity和Fragment的转场动画
- Android Activity和Fragment的转场动画
- Android Activity和Fragment的转场动画
- Android Activity和Fragment的转场动画
- 浅谈操作系统对内存的管理
- 最少硬币问题
- 【BLE】CC2541之设置发射功率
- 一个窗帘引发的——关于测试及测试活动的思考(一)
- 每天学习十分钟18之工作笔记(等于号)
- IOS7的转场动画和CATransform3D简单使用
- Oracle备份失败(ANS0350E)
- KVC与KVO
- ARM64 Linux的启动分析
- The Java™ Tutorials — Generics :Why Use Generics? 为什么使用泛型
- 接口测试-Swagger介绍
- suricata的ips模式
- SwipeRefreshLayout使用注意的坑
- Spring MVC