动画
首先我们先回顾下图中的View动画
UIView基础动画实现方式一
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//创建一个动画
[UIView beginAnimations:nil context:nil];
//动画延迟
[UIView setAnimationDelay:2];
//给动画添加代理(此代理协议可以不写,也能实现代理方法)
[UIView setAnimationDelegate:self];
//给动画添加方法(动画结束后执行)
[UIView setAnimationDidStopSelector:@selector(test)];
//动画持续时间
[UIView setAnimationDuration:2];
//设置动画效果是否会自动重复播放
[UIView setAnimationRepeatAutoreverses:NO];
//用以上动画效果,使声明好的label属性从自己原来给的布局的位置移动到下边新的位置
self.label.frame = CGRectMake(100, 100, 100, 100);
//开始动画命令
[UIView commitAnimations];
}
- (void)test{
NSLog(@"动画结束");
}
UIView基础动画实现方式二
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//实现动画的block_1
//开始一个动画,block中写入实现动画
// [UIView animateWithDuration:2 animations:^{
// self.label.frame = CGRectMake(100, 100, 100, 100);
// }];
// //实现动画的block_2
// [UIView animateWithDuration:2 animations:^{
// self.label.frame = CGRectMake(100, 100, 100, 100);
// }completion:^(BOOL finished) {
// NSLog(@"%d=动画结束",finished);
//
// }];
// //实现动画的block_3
// [UIView animateWithDuration:2 delay:2 options:(UIViewAnimationOptionCurveEaseInOut) animations:^{
// self.label.frame = CGRectMake(100, 100, 100, 100);
// } completion:^(BOOL finished) {
// NSLog(@"%d = 动画结束",finished);
// }];
// //实现动画的block_4
// //Spring:模拟弹簧效果
// //Damping:阻尼, 从0~1,值越小,动画越明显
// //initialSpringVelocity:动画初始变化速率
// [UIView animateWithDuration:2 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:150 options:(UIViewAnimationOptionCurveEaseInOut) animations:^{
// self.label.center = CGPointMake(self.view.center.x, 100);
// } completion:^(BOOL finished) {
// NSLog(@"动画结束%d",finished);
// }];
//实现动画的block_5(关键帧动画)
[UIView animateKeyframesWithDuration:3 delay:0 options:(UIViewKeyframeAnimationOptionRepeat) animations:^{
//relativeDuration:设置为0.5,实际时间为0.5*3
[UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.5 animations:^{
self.label.center = self.view.center;
}];
} completion:^(BOOL finished) {
NSLog(@"%d完成了",finished);
}];
}
下边我们就来看下Layer动画
- 1.核心动画的基本概念:
- 1.1.coreAnimation核心动画,一组非常强大的动画处理API,可以用少量的代码,实现强大的功能.
- 1.2.CoreAnimation可以用在Mac OS和iOS两个平台
- 1.3.CoreAnimation动画的执行过程,都在后台操作,不会阻塞主线程
- 1.4.CoreAnimation直接操作CALayer层,并不是UIView
- 2.CAAnimation
- 2.1.CAAnimation是所有动画对象的父类,负责控制动画的持续时间,和速度,它是一个抽象类,不能直接使用,应该使用它的子类
-
2.2.属性说明:
①:duration:动画持续时间
②:repeatCount:动画的重复次数
③:repeatDuration:重复时间
④:removeOnCompletion(BOOL):默认为YES,表示动画执行完毕后就从图层上移除,图形会恢复到执行之前的状态.若想保持动画执行之后的状态,那就设置为NO,但是,还需要设置fillModel值为KCAFillModelForwards
⑤:fillMode:决定当前对象在非活动的时间段的行为,比如动画开始之前或者动画结束之后(想要fillMode有效,最好将removeOnCompletion=NO)- KCAFillModelRemove:默认值就是说当前动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
- KCAFillModelForwards:当前动画结束后,layer会一直保存最后状态
- KCAFillModeBackwards:在动画开始之前,只需将动画加入一个layer,layer便立即进入动画的初始状态并等待动画开始
- KCAFillModelBoth:KCAFillModelForwards和KCAFillModeBackwards的合成
⑥:beginTime:可用来设置动画延迟时间,若想延迟两秒,则设置为CACurrentMediaTime()+2.其中的CACurrentMediaTime()为图层当前的时间
⑦timingFunction:速度控制函数,控制动画运行的节奏
- CAMediaTimingFunctionLinear(线性):匀速.给你一个相对静态的感觉
- CAMediaTimingFunctionEaseIn(淡入):动画缓慢进入,然后加速离开
- CAMediaTimingFunctionEaseOut(淡出):动画全速进入,然后减速到达目的地
- 2.3CAAnimation的子类:
- 2.3.1CABasicAnimation
- 2.3.2CAKeyFrameAnimation
- 2.3.3CAAnimationGroup
- 2.3.4CASpringAnimation
- 2.4属性说明
keypath:通过指定CALayer的一个属性名称为keypath(NSSting类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果,比如,指定@"position"为keypath,就相当于修改了CALayer的position属性的值,达到平移动画的效果
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
#pragma mark -----------------CABasicAnimation---------------
//1.创建
//缩放动画
CABasicAnimation *basic1 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
basic1.fromValue = [NSNumber numberWithFloat:0.8f];
basic1.toValue = [NSNumber numberWithFloat:2.0f];
//旋转动画
CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
basic.toValue = [NSNumber numberWithFloat:M_PI*4];
//动画效果的初始值
basic.fromValue = @50;
//动画效果变换的结束值(绝对值)
basic.toValue = @80;
//动画执行时间
basic.duration = 4;
// [_label.layer addAnimation:basic forKey:@"aaa"];
#pragma mark -----------------CAKeyFrameAnimation---------------
CAKeyframeAnimation *keyframe = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGPoint p1= CGPointMake(0, 0);
CGPoint p2= CGPointMake(0, 400);
CGPoint p3= CGPointMake(400, 100);
CGPoint p4= CGPointMake(100, 200);
CGPoint p5= CGPointMake(200, 300);
NSValue *v1 = [NSValue valueWithCGPoint:p1];
NSValue *v2 = [NSValue valueWithCGPoint:p2];
NSValue *v3 = [NSValue valueWithCGPoint:p3];
NSValue *v4 = [NSValue valueWithCGPoint:p4];
NSValue *v5 = [NSValue valueWithCGPoint:p5];
//values:NSArray对象,里面的元素称为"keyFrame(关键帧)",动画对象会在指定的时间里,依次显示values数组中的每一个关键帧
keyframe.values = @[v1,v2,v3,v4,v5];
keyframe.duration = 10;
//可以设置每一帧的时间为比例的累加计算,取值范围0~1,若没设置,那么每一帧时间平分
keyframe.keyTimes = @[@(0.1),@(0.2),@(1),@(1)];
//将动画添加在layer层
// [self.label.layer addAnimation:keyframe forKey:@"bbb"];
#pragma mark -----------------CAAnimationGroup---------------
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[basic1,basic,keyframe];
group.duration = 10;
// [self.label.layer addAnimation:group forKey:@"ccc"];
#pragma mark-------CASpringAnimation------
CASpringAnimation *spring = [CASpringAnimation animationWithKeyPath:@"position.x"];
//设置动画效果的初始值
spring.fromValue = @150;
//设置动画效果的结束值
spring.toValue = @102;
//阻尼系数
spring.damping = 0;
//刚度系数:(进度系数/弹性系数),系数越大,形变产生力越大,运动越快.
spring.stiffness = 100;
//质量:影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩幅度越大,动画运动波动大
spring.mass = 50;
//初始速率,速率为正,速度方向和运动方向一致,否则相反.
spring.initialVelocity = -1;
//结算时间,返回弹簧动画到停止时的估算时间,根据当前动画的各个参数估算,通常弹簧动画的时间使用结算时间比较准确
spring.duration = spring.settlingDuration;
[self.label.layer addAnimation:spring forKey:@"dddd"];
}
- 3.关键帧动画与CABasicAnimation的区别
- 3.1CABasicAnimation只能从一个数值(fromValue)变换到另一个数值(toValue)
- 3.2关键帧动画,会使用一个NSArray保存这些数值
- 4.动画组
- 4.1属性说明:
animation:用来保存一组动画对象的NSArray.
-
4.1.2默认情况下,一组动画对象是同时运动的,也可通过设置动画的beginTime属性来更改动画开始时间
-
5.转场动画
CATransition:用于做转场动画效果,能够为layer层提供移除屏幕和移入屏幕的动画效果- 5.1动画属性
- 5.1.1type:动画的过度效果
- 5.1.2subtype:动画的过度方向
- 5.1.3startProgress:动画起点(在整体动画的百分比)
- 5.1.4endProgress:动画终点
- (void)viewDidLoad {
[super viewDidLoad];
_imageview = [[UIImageView alloc]init];
_imageview.frame = [[UIScreen mainScreen]bounds];
//图片在view上显示,且比例不变
_imageview.contentMode = UIViewContentModeScaleAspectFit;
self.imageview.image = [UIImage imageNamed: @"1.jpg"];
[self.view addSubview:self.imageview];
//添加手势
UISwipeGestureRecognizer *left = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(leftSwipe)];
[left setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.view addGestureRecognizer:left];
UISwipeGestureRecognizer *right = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(rightSwipe)];
[right setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.view addGestureRecognizer:right];
}
- (void)leftSwipe{
[self transitionAnimation:YES];
}
- (void)rightSwipe{
[self transitionAnimation:NO];
}
- (void)transitionAnimation:(BOOL)isNext{
//创建专场动画
CATransition *tran = [[CATransition alloc]init];
//效果
tran.type = @"cube";
// // 动画的开始位置(0——1)
// tran.startProgress = 0;//默认为0
// // 动画的结束位置
// tran.endProgress = 1;//默认为1
if (isNext) {
tran.subtype = kCATransitionFromRight;
}else{
tran.subtype = kCATransitionFromLeft;
}
tran.duration = 1.0f;
self.imageview.image = [self getImage:isNext];
[self.imageview.layer addAnimation:tran forKey:@"Transition"];
}
- (UIImage *)getImage:(BOOL)isNext{
if (isNext) {
//eg:当currentIndex = 1时,(1+1)%5 = 2;
self.currentIndex = (self.currentIndex +1)%IMAGE_COUNT;//IMAGE_COUNT宏定义照片总数
}
//前一张
else{
//eg:当currentIndex = 1时,(1-1+5)%5 = 0;
self.currentIndex = (self.currentIndex -1+IMAGE_COUNT)%IMAGE_COUNT;
}
NSString *imageName = [NSString stringWithFormat:@"%ld.jpg",self.currentIndex +1];
return [UIImage imageNamed:imageName];
}
CATransition的type效果表
类型字符串 | 效果说明 |
---|---|
fade | 交叉淡化过渡 |
push | 新视图把旧视图推出去 |
moveIn | 新视图移到旧视图上面 |
reveal | 将旧视图移开,显示下面的新视图 |
cube | 立方体翻转效果 |
oglFlip | 上下左右翻转效果 |
suckEffect | 收缩效果,像一块布被抽走 |
rippleEffect | 水滴效果 |
pageCurl | 向上翻页效果 |
pageUnCurl | 向下翻页效果 |
cameraIrisHollowOpen | 相机镜头打开效果 |
cameraIrisHollowClose | 相机镜头关闭效果 |
---------------------------------CALayer----------------------------
1.在iOS中,我们能看得见的,如按钮,文本,标签,输入框,等待,都是UIView
2.其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层,在创建UIView对象时,UIView内部会自动创建一个图层(CALayer对象),通过UIView的layer属性可以访问这个层
3.@property(nonatomic, strong)CALayer *layer;
4.当UIView需要显示在屏幕时,会调用drawRect:方法进行绘图,并且将所有绘制的内容在自己的图层上绘制,图层绘制完毕,系统将会拷贝图层到屏幕上,完成UIView的显示
5.UIView本身是布局有显示功能,真正拥有显示功能的是里面的layer层
6.通过UIView的图层,可以调整UIView的一些界面属性eg:圆角,边框,阴影
CALayer的坐标系统比UIView多了一个anchorPoint属性
anchorPoint锚点相对自身bounds来说,默认值为(0.5,0.5),即是anchorPoint的默认值在layer的中心点,它的值在0~1之间
- (void)viewlayer{
//设置阴影,透明度
self.myview.layer.shadowOpacity = 1;
//设置阴影色
_myview.layer.shadowColor = [UIColor yellowColor].CGColor;
//设置阴影圆角半径
self.myview.layer.shadowRadius = 25;
//设置圆角
_myview.layer.cornerRadius = 100;
// _myview.layer.masksToBounds = YES;
//设置边框半径
self.myview.layer.borderColor = [UIColor redColor].CGColor;
//设置边框半径
_myview.layer.borderWidth = 25;
}
- (void)Layer{
CALayer *layer = [CALayer layer];
layer.bounds = CGRectMake(0, 0, 100, 100);
//设置位置
layer.position = CGPointMake(200, 200);
// layer.anchorPoint = CGPointMake(0, 0);
layer.backgroundColor = [UIColor magentaColor].CGColor;
[self.view.layer addSublayer:layer];
}