Quartz2D复习(四) --- 图层CALayer和动画CAAnimation
1、CALayer
1)、在ios中,能看得见摸得着的东西基本上都是UIView, 比如按钮、文本标签、文本输入框、图标等,这些都是UIView
2)、UIView之所以能显示在屏幕上,完全是因为它内部的一个图层
3)、在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层:@property (nonatomic,readonly,retain) CALayer *layer;
4)、当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示。UIView本身不具备显示的功能,是它内部的层才有显示功能
5)、通过CALayer对象,可以很方便的调整UIView的一些外观属性,比如:阴影、圆角大小、边框宽度和颜色。。。,还可以给图层添加动画,来实现一些比较炫酷的效果
6)、CALayer属性:
@property CGRect bounds; //宽度和高度
@property CGPoint position; //位置(默认指中点,具体由anchorPoint决定)
@property CGPoint anchorPoint; //锚点(x、y的范围都是0->1),决定了position的含义
@property CGColorRef backgroundColor; //背景颜色(CGColorRef类型)
@property CATransform3D transform; //形变属性
@property CGColorRef borderColor; //边框颜色(CGColorRef类型)
@property CGFloat borderWidth; //边框宽度
@property CGFloat conerRadius; //圆角半径
@property id contents; //内容(比如设置图片CGImageRef)
@property CGColorRef shadowColor; //阴影颜色
@property float shadowOpacity; //阴影不透明(取值范围0.0 -> 1.0)
@property CGSize shadowOffset; //阴影偏移位置
7)、CALayer是定义在QuartzCore框架中的[Core Animation];
CGImageRef、CGColorRef两种数据类型是定义在CoreGraphics框架中;
UIColor、UIImage是定义在UIKit框架中的;
QuartzCore框架和CoreGraphics框架是可以跨平台使用的,在ios和Mac OSX上能使用;
但是UIKit只能在ios中使用;为了保证可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef
8)、UIView和CALayer的比较
通过CALayer,可以做出跟UIView一样的界面效果;但是UIView多了一个事件处理的功能,CALayer不能处理用户的触摸事件;
不过CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级
9)、每个UIView内部都默认关联着一个CALayer, 我们可以称这个CALayer为RootLayer(跟层);
所有的非RootLayer, 也就是手动创建的CALayer对象,都存在着隐式动画;
隐式动画是指当对非RootLayer的部分属性进行修改时,默认会自动产生一些动画效果;这些属性称为Animatable Properties(可动画属性)
几个常见的Animatable Properties: bounds、backgroundColor、position
可以通过动画事务(CATransaction)关闭默认的隐式动画效果:
[CATransaction begin];
[CATransaction setDisableActions: YES];
self.myView.layer.position = CGPointMake(, );
[CATransaction commit];
2、Core Animation
1)、Core Animation是一组非常强大的动画处理API, 使用它能做出非常绚丽的动画效果,少量的代码可以实现非常强大的功能
2)、Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程
3)、Core Animation是直接操作在CALayer上的,并非UIView
4)、CAAnimation继承结构,紫色虚线表示继承自某类,红色虚线表示遵守某个协议
:
5)、CAAnimation
是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,只能使用它具体的子类。
属性说明:
duration: 动画的持续时间
repeatCount: 重复次数,无限循环可以设置HUGE_VALF或MAXFLOAT
repeatDuration: 重复时间
removeOnCompletion : 默认为YES, 代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,
不过还要设置fillMode为kCAFillModeForwards
fillMode : 决定当前对象在非activate时间段的行为。比如动画开始之前或者动画结束之后
beginTime : 可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2, CACurrentMediaTime()为图层的当前时间
timingFunction: 速度控制函数,控制动画运行的节奏
delegate : 动画代理
6)、fillMode属性值(要想fillMode有效,最好设置removedOnCompletion = NO)
kCAFillModeRemoved : 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响;动画结束后,layer会恢复到之前的状态
kCAFillModeForwards : 当动画结束后,layer会一直保持这动画最后的状态
kCAFillModeBackwards : 在动画开始前,只需要将动画加入了一个layer, layer便立刻进入动画的初始状态并等待动画开始
kCAFillModeBoth : 是kCAFillModeForwards和kCAFillModeBackwards的合成,动画加入后开始之前,layer便处于动画出事状态,动画结束后layer保持动画最后的状态
7)速度控制函数(CAMediaTimingFunction)
kCAMediaTimingFunctionLinear (线性):匀速,给你一个相对静态的感觉
kCAMediaTimingFunctionEaseIn (渐进): 动画缓慢进入,然后加速离开
kCAMediaTimingFunctionEaseOut (渐出): 动画全速进入,然后减速的到达目的地
kCAMediaTimingFunctionEaseInEaseOut (渐进渐出): 动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为
8)CAAnimationDelegate 动画代理方法
/* Called when the animation begins its active duration */
- (void)animationDidStart: (CAAnimation *)anim;
/* Called when the animation either completes its active duration or is removed from the object it is attached to (i.e. the layer). 'flag'
is true is the animation reached the end of its activate duration without beging removed. */
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
9)、CAPropertyAnimation
CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:
CABasicAnimation 和 CAKeyframeAnimation
属性说明:
keyPath: 通过指定CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。
比如指定@"position"为keyPath, 就修改CALayer的position属性的值,已达到平移的动画效果
10)、CABasicAnimation -- 基本动画
属性说明:
fromValue : keyPath相应属性的初始值
toValue: keyPath相应属性的结束值
动画过程说明: 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐的变为toValue;
如果fillMode = kCAFillModeForwards 同时removedOnCompletion = NO, 那么在动画执行完毕后,图层会保持显示动画执行后的状态。但是实质上,
图层的属性值还是动画执行前的初始值,并没有真正的被改变
11)、CAKeyframeAnimation --- 关键帧动画
关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是:
CABasicAnimation只能从一个数值(fromValue) 变到另一个数值(toValue), 而CAKeyframeAnimation会使用一个NSArray保存这些数值
属性说明:
values: NSArray对象。里面的元素称为“关键帧”【keyframe】。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
path: 可以设置一个CGPathRef、CGMutablePathRef, 让图层按照路径轨迹移动。path只对CALayer的anthorPoint和position起作用。如果设置了path,那么values将被忽略
keyTimes: 可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0, keyTimes中的每个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的
12)、CAAnimationGroup --- 动画组
动画组,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行
属性说明:
animations: 用来保存一组动画对象的NSArray。默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间
13)、转场动画 --- CATransition
CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移除屏幕和移入屏幕的动画效果。ios比Mac OSX的转场动画效果少一点
UINavigationController就是通过CATransation实现了将控制器的视图推入屏幕的动画效果
动画属性:
type : 动画过度类型
subtype : 动画过度方向
startProgress : 动画起点(在整体动画的百分比)
endProgress : 动画终点(在整体动画的百分比)
转场动画过度效果:
14)、使用UIView动画函数实现转场动画
+ (void) transitionWithView:(UIView *)view duration: (NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;
参数说明:
duration : 动画的持续时间
view : 需要进行转场动画的视图
options : 转场动画的类型
animations : 将改变视图属性的代码放在这个block中
completion : 动画结束后,会自动调用这个block
15)、CADisplayLink
CADisplayLink是一种以锁屏幕刷新频率触发的时钟机制,每秒钟执行大约60次左右;
CADisplayLink是一个计时器,可以使绘图代码与视图的刷新频率保持同步,而NSTimer无法确保计时器实际被触发的准确时间
使用方法:
定义CADisplayLink并制定触发调用方法
将显示链接添加到主运行循环队列
3、代码演示
1)时钟器,和当前计算机时间同步,先看截图:
代码:
#import <UIKit/UIKit.h> @interface ClockViewController : UIViewController @end
// 演示时钟器 #import "ClockViewController.h" @interface ClockViewController () @property (nonatomic, retain) UIImageView *imgView; //时钟器
@property (nonatomic, retain) CALayer *hourLayer; //时针
@property (nonatomic, retain) CALayer *minuteLayer; //分针
@property (nonatomic, retain) CALayer *secondLayer; //秒针 @end @implementation ClockViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view setBackgroundColor:[UIColor whiteColor]]; [self addImgAndLayer]; //添加子控件
[self updateClockTime]; //更新时间 [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateClockTime) userInfo:nil repeats:YES]; //每隔一秒重复运行
} //添加UIImageView和时分秒针
- (void)addImgAndLayer{
//1、添加UIImageView
UIImage *img = [UIImage imageNamed:@"clock"];
UIImageView *imgV = [[UIImageView alloc] initWithImage:img];
[self.view addSubview:imgV];
self.imgView = imgV;
CGFloat width = imgV.frame.size.width;
CGFloat height = imgV.frame.size.height;
[self.imgView setFrame:CGRectMake(( - width) * 0.5, , width, height)]; //2、添加时针
CALayer *hourLa = [CALayer layer];
hourLa.anchorPoint = CGPointMake(0.5, 0.8);
hourLa.position = imgV.center;
[hourLa setBounds:CGRectMake(, , , height * 0.5 - )];
hourLa.cornerRadius = ;
[hourLa setBackgroundColor:[UIColor grayColor].CGColor];
[self.view.layer addSublayer:hourLa];
self.hourLayer = hourLa; //3、添加分针
CALayer *minuteLa = [CALayer layer];
minuteLa.anchorPoint = CGPointMake(0.5, 0.8);
minuteLa.position = imgV.center;
[minuteLa setBounds:CGRectMake(, , , height * 0.5 - )];
minuteLa.cornerRadius = ;
[minuteLa setBackgroundColor:[UIColor purpleColor].CGColor];
[self.view.layer addSublayer:minuteLa];
self.minuteLayer = minuteLa; //4、添加秒针
CALayer *secondLa = [CALayer layer];
secondLa.anchorPoint = CGPointMake(0.5, 0.8);
secondLa.position = imgV.center;
[secondLa setBounds:CGRectMake(, , , height * 0.5 - )];
secondLa.cornerRadius = ;
[secondLa setBackgroundColor:[UIColor yellowColor].CGColor];
[self.view.layer addSublayer:secondLa];
self.secondLayer = secondLa; //添加返回按钮
UIButton *preBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[preBtn setTitle:@"返回" forState:UIControlStateNormal];
[preBtn setFrame:CGRectMake(, , , )];
[preBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[preBtn addTarget:self action:@selector(prePage) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:preBtn];
} //改变时间
- (void)updateClockTime{
//1、获取日历控件
NSCalendar *calendar = [NSCalendar currentCalendar];
//2、获取时间组成部分(时分秒)
NSDateComponents *dateCom = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:[NSDate date]]; //3、获取时分秒针旋转角度
CGFloat angle = * M_PI / 60.0; //每个小格子所占的角度
CGFloat secondAngle = dateCom.second * angle; //秒针的位置
CGFloat minuteAngle = (dateCom.minute + dateCom.second / 60.0) * angle;//分针的角度位置
CGFloat hourAngle = (dateCom.hour % ) * * M_PI / + dateCom.minute * angle * / ; //时针的角度位置
//NSLog(@"xiaoshi : %f, %d", hourAngle, dateCom.hour); //4、从新旋转图层
self.secondLayer.transform = CATransform3DMakeRotation(secondAngle, , , );
self.minuteLayer.transform = CATransform3DMakeRotation(minuteAngle, , , );
self.hourLayer.transform = CATransform3DMakeRotation(hourAngle, , , );
} //返回上一页
- (void)prePage{
[self dismissViewControllerAnimated:YES completion:nil];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} /*
#pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/ @end
2) 、各种动画演示:
代码:
AnimationViewController.h文件
#import <UIKit/UIKit.h> @interface AnimationViewController : UIViewController @end
AnimationViewController.m文件
// 图层动画
// #import "AnimationViewController.h" @interface AnimationViewController () @property (nonatomic, retain) UIImageView *imgView;
@property (nonatomic, retain) UIImageView *imgView2;
@property (nonatomic, assign) NSInteger index; @end @implementation AnimationViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view setBackgroundColor:[UIColor whiteColor]]; [self addPreBtn]; //增加返回按钮
[self testLayer]; //图层
} - (void)testLayer{
//1、增加UIView
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(, , , )];
[self.view addSubview:view];
view.layer.backgroundColor = [UIColor redColor].CGColor;
view.layer.cornerRadius = ; //图层半径: 50刚好一个圆;小于50为一个圆角方形, 大于50为变型的图形 view.layer.borderWidth = ;
view.layer.borderColor = [UIColor greenColor].CGColor;
//阴影
view.layer.shadowColor = [UIColor yellowColor].CGColor;
view.layer.shadowRadius = ;
view.layer.shadowOpacity = ; //1表示阴影不透明;0表示透明,阴影看不见 //1.2增加子图层
CALayer *subLayer = [[CALayer alloc] init];
subLayer.position = CGPointMake(, );
subLayer.anchorPoint = CGPointMake(0.5, );
subLayer.bounds = CGRectMake(, , , );
[subLayer setBackgroundColor:[UIColor purpleColor].CGColor];
[view.layer addSublayer:subLayer]; //2、增加UIImageView
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(, , , )];
imgView.image = [UIImage imageNamed:@"first"];
[self.view addSubview:imgView];
imgView.layer.cornerRadius = ; //等于50刚好裁剪一个圆;小雨50为圆角方形;大于50变形
imgView.layer.masksToBounds = YES; //现实裁剪
imgView.layer.borderWidth = ;
imgView.layer.borderColor = [UIColor redColor].CGColor;
imgView.layer.shadowRadius = ;
self.imgView = imgView;
// imgView.layer.shadowColor = [UIColor redColor].CGColor;
// imgView.layer.shadowOpacity = 1; //3、添加按钮测试形变
UIButton *moveBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[moveBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[moveBtn setTitle:@"移动" forState:UIControlStateNormal];
[moveBtn setFrame:CGRectMake(, , , )];
[moveBtn addTarget:self action:@selector(moveImgView:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:moveBtn]; //4、添加X方向旋转按钮
UIButton *rotationBtnX = [UIButton buttonWithType:UIButtonTypeCustom];
[rotationBtnX setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[rotationBtnX setTitle:@"X旋转" forState:UIControlStateNormal];
[rotationBtnX setFrame:CGRectMake(, , , )];
[rotationBtnX addTarget:self action:@selector(rotationXImgView:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:rotationBtnX]; //5、添加Y方向旋转按钮
UIButton *rotationBtnY = [UIButton buttonWithType:UIButtonTypeCustom];
[rotationBtnY setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[rotationBtnY setTitle:@"Y旋转" forState:UIControlStateNormal];
[rotationBtnY setFrame:CGRectMake(, , , )];
[rotationBtnY addTarget:self action:@selector(rotationYImgView:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:rotationBtnY]; //6、添加Z方向旋转按钮
UIButton *rotationBtnZ = [UIButton buttonWithType:UIButtonTypeCustom];
[rotationBtnZ setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[rotationBtnZ setTitle:@"Z旋转" forState:UIControlStateNormal];
[rotationBtnZ setFrame:CGRectMake(, , , )];
[rotationBtnZ addTarget:self action:@selector(rotationZImgView:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:rotationBtnZ]; //7、添加缩放按钮
UIButton *scaleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[scaleBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[scaleBtn setTitle:@"缩放" forState:UIControlStateNormal];
[scaleBtn setFrame:CGRectMake(, , , )];
[scaleBtn addTarget:self action:@selector(scaleImgView:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:scaleBtn]; ///////// 动画演示 、、、、、、、、
//0、增加一个UIImageView
UIImageView *imgView2 = [[UIImageView alloc] initWithFrame:CGRectMake(, , , )];
imgView2.image = [UIImage imageNamed:@"first"];
[self.view addSubview:imgView2];
imgView2.layer.cornerRadius = ; //等于50刚好裁剪一个圆;小雨50为圆角方形;大于50变形
imgView2.layer.masksToBounds = YES; //现实裁剪
imgView2.layer.borderWidth = ;
imgView2.layer.borderColor = [UIColor redColor].CGColor;
imgView2.layer.shadowRadius = ;
imgView2.userInteractionEnabled = YES; //增加交互
self.imgView2 = imgView2; //1、动画缩放默认还原
UIButton *scaleAniBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[scaleAniBtn setTitle:@"动画缩放" forState:UIControlStateNormal];
[scaleAniBtn setFrame:CGRectMake(, , , )];
[scaleAniBtn addTarget:self action:@selector(ainimationScale) forControlEvents:UIControlEventTouchUpInside];
[scaleAniBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[self.view addSubview:scaleAniBtn]; //2、动画缩放后不还原
UIButton *scaleAniBtnNoRevert = [UIButton buttonWithType:UIButtonTypeCustom];
[scaleAniBtnNoRevert setTitle:@"动画缩放后不还原" forState:UIControlStateNormal];
[scaleAniBtnNoRevert setFrame:CGRectMake(, , , )];
[scaleAniBtnNoRevert.titleLabel setFont:[UIFont systemFontOfSize:]];
[scaleAniBtnNoRevert addTarget:self action:@selector(ainimationScaleNoRevert:) forControlEvents:UIControlEventTouchUpInside];
[scaleAniBtnNoRevert setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[self.view addSubview:scaleAniBtnNoRevert]; //3、增加动画移动
UIButton *moveAniBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[moveAniBtn setTitle:@"动画移动" forState:UIControlStateNormal];
[moveAniBtn setFrame:CGRectMake(, , , )];
[moveAniBtn.titleLabel setFont:[UIFont systemFontOfSize:]];
[moveAniBtn addTarget:self action:@selector(animationMoveTransation:) forControlEvents:UIControlEventTouchUpInside];
[moveAniBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[self.view addSubview:moveAniBtn]; //4、动画集合
UIButton *mulAniBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[mulAniBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[mulAniBtn setTitle:@"动画集" forState:UIControlStateNormal];
[mulAniBtn addTarget:self action:@selector(animationKeyframe) forControlEvents:UIControlEventTouchUpInside];
[mulAniBtn setFrame:CGRectMake(, , , )];
[self.view addSubview:mulAniBtn]; //5、动画集合2 ,使用UIBearPath
UIButton *mulAniBtn2 = [UIButton buttonWithType:UIButtonTypeCustom];
[mulAniBtn2 setTitle:@"动画集2" forState:UIControlStateNormal];
[mulAniBtn2 setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[mulAniBtn2 addTarget:self action:@selector(animationKeyframe2) forControlEvents:UIControlEventTouchUpInside];
[mulAniBtn2 setFrame:CGRectMake(, , , )];
[self.view addSubview:mulAniBtn2]; //6、长按抖动,动画集合3
UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(animationKeyframe3:)];
[self.imgView2 addGestureRecognizer:gesture]; //给imgView2增加长按手势
//7、第三行按钮: 取消抖动
UIButton *cancelDou = [UIButton buttonWithType:UIButtonTypeCustom];
[cancelDou setTitle:@"取消抖动" forState:UIControlStateNormal];
[cancelDou setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[cancelDou setFrame:CGRectMake(, , , )];
[cancelDou addTarget:self action:@selector(removeAnimation) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:cancelDou]; //8、转场动画
UIButton *trasitionBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[trasitionBtn setTitle:@"转场动画" forState:UIControlStateNormal];
[trasitionBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[trasitionBtn addTarget:self action:@selector(trasactionAnimation) forControlEvents:UIControlEventTouchUpInside];
[trasitionBtn setFrame:CGRectMake(, , , )];
[self.view addSubview:trasitionBtn]; //9、动画组
UIButton *groupAniBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[groupAniBtn setTitle:@"动画组" forState:UIControlStateNormal];
[groupAniBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[groupAniBtn addTarget:self action:@selector(animationGroup) forControlEvents:UIControlEventTouchUpInside];
[groupAniBtn setFrame:CGRectMake(, , , )];
[self.view addSubview:groupAniBtn];
} //移动UIImageView
- (void)moveImgView:(UIButton *)sender{
[UIView animateWithDuration: animations:^{
if (sender.tag == ){
self.imgView.layer.transform = CATransform3DMakeTranslation(-, , );
sender.tag = ;
}else{
sender.tag = ;
self.imgView.layer.transform = CATransform3DTranslate(self.imgView.layer.transform, , -, );
}
}];
} //X旋转UIImageView
- (void)rotationXImgView:(UIButton *)sender{
[UIView animateWithDuration: animations:^{
self.imgView.layer.transform = CATransform3DRotate(self.imgView.layer.transform, M_PI, , , );
}];
}
//Y旋转UIImageView
- (void)rotationYImgView:(UIButton *)sender{
[UIView animateWithDuration:1.0 animations:^{
self.imgView.layer.transform = CATransform3DRotate(self.imgView.layer.transform, M_PI, , , );
}];
}
//Z旋转UIImageView
- (void)rotationZImgView:(UIButton *)sender{
[UIView animateWithDuration:1.0 animations:^{
self.imgView.layer.transform = CATransform3DRotate(self.imgView.layer.transform, M_PI, , , );
}];
} //缩放
- (void)scaleImgView:(UIButton *)sender{
[UIView animateWithDuration: animations:^{
if (sender.tag == ){
self.imgView2.layer.transform = CATransform3DMakeScale(0.5, 0.5, 0.0);
sender.tag = ;
}else{
sender.tag = ;
self.imgView2.layer.transform = CATransform3DMakeScale(1.0, 1.0, 0.0);
}
}];
} //动画缩放
- (void)ainimationScale{
CABasicAnimation *basicAni = [CABasicAnimation animation];
basicAni.keyPath = @"transform.scale";
basicAni.toValue = @0.1;
basicAni.duration = ;
[self.imgView2.layer addAnimation:basicAni forKey:nil];
} //动画缩放不还原
- (void)ainimationScaleNoRevert:(UIButton *)sender{
CABasicAnimation *basicAni = [CABasicAnimation animation];
basicAni.keyPath = @"transform.scale"; if (sender.tag == ){
basicAni.toValue = @1.5;
sender.tag = ;
}else{
basicAni.toValue = @0.5;
sender.tag = ;
}
basicAni.duration = ;
//fillMode和removeOnCompletion两个属性都需要设置才能不还原
basicAni.fillMode = kCAFillModeForwards; //默认填充模式为一直向前
basicAni.removedOnCompletion = NO; //完成动画后不移除动画
[self.imgView2.layer addAnimation:basicAni forKey:nil];
} //动画位置移动
- (void)animationMoveTransation:(UIButton *)sender{
CABasicAnimation *basicAni = [CABasicAnimation animation];
basicAni.keyPath = @"position"; if (sender.tag == ){
basicAni.toValue = [NSValue valueWithCGPoint:CGPointMake(, )];
sender.tag = ;
}else{
basicAni.toValue = [NSValue valueWithCGPoint:CGPointMake(, )];
sender.tag = ;
}
basicAni.duration = ;
//fillMode和removeOnCompletion两个属性都需要设置才能不还原
basicAni.fillMode = kCAFillModeForwards; //默认填充模式为一直向前
basicAni.removedOnCompletion = NO; //完成动画后不移除动画
[self.imgView2.layer addAnimation:basicAni forKey:nil];
} //动画集合,测试CAKeyframeAnimation
- (void)animationKeyframe{
CAKeyframeAnimation *keyAni = [CAKeyframeAnimation animation];
NSValue *val1 = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue *val2 = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue *val3 = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue *val4 = [NSValue valueWithCGPoint:CGPointMake(, )];
keyAni.values = @[val1, val2, val3, val4];
keyAni.keyPath = @"position";
keyAni.duration = ;
[self.imgView2.layer addAnimation:keyAni forKey:nil];
}
//测试UIBezierPath动画集合
- (void)animationKeyframe2{
CAKeyframeAnimation *keyAni = [CAKeyframeAnimation animation];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(, , , )];
keyAni.path = path.CGPath;
keyAni.duration = ;
keyAni.keyPath = @"position";
[self.imgView2.layer addAnimation:keyAni forKey:nil];
}
//动画集合3,长按抖动
- (void)animationKeyframe3: (UILongPressGestureRecognizer *)sender{
if (sender.state == UIGestureRecognizerStateBegan){
CAKeyframeAnimation *keyAni = [CAKeyframeAnimation animation];
keyAni.keyPath = @"transform.rotation";
keyAni.values = @[@(-M_PI_4 * 0.6), @(), @(M_PI_4 * 0.6), @(), @(-M_PI_4 * 0.6)];
keyAni.repeatCount = MAXFLOAT;
keyAni.duration = 0.2;
[self.imgView2.layer addAnimation:keyAni forKey:nil];
}
} //取消抖动动画
- (void)removeAnimation{
[self.imgView2.layer removeAllAnimations];
} //转场动画
- (void)trasactionAnimation{
_index++;
if (_index > ){
_index = ;
} CATransition *tra = [CATransition animation];
tra.subtype = @"fromLeft";
tra.type = @"push"; //push推送(把前一个推走); moveIn移进去(慢慢覆盖前一个), fade:慢慢消失,默认; reveal:离开
tra.duration = 0.5;
self.imgView2.image = [UIImage imageNamed:[NSString stringWithFormat:@"%i", _index]]; [self.imgView2.layer addAnimation:tra forKey:nil];
} //动画组
- (void)animationGroup{
CABasicAnimation *rotation = [CABasicAnimation animation];
rotation.keyPath = @"transform.rotation";
rotation.toValue = @M_PI;//[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, 0, 0)]; CABasicAnimation *scale = [CABasicAnimation animation];
scale.keyPath = @"transform.scale";
scale.toValue = @;//[NSValue valueWithCATransform3D:CATransform3DMakeScale(3, 3, 1)]; CABasicAnimation *position = [CABasicAnimation animation];
position.keyPath = @"position";
position.toValue = [NSValue valueWithCGPoint:CGPointMake(, )]; CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[scale, position, rotation];
group.duration = ;
// group.removedOnCompletion = NO;
// group.fillMode = kCAFillModeForwards;
[self.imgView2.layer addAnimation:group forKey:nil];
} //增加上一页按钮
- (void)addPreBtn{
UIButton *preBtn = [[UIButton alloc] initWithFrame:CGRectMake(, , , )];
[preBtn setTitle:@"上一页" forState:UIControlStateNormal];
[preBtn setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
[preBtn addTarget:self action:@selector(previousPage) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:preBtn];
} //上一页
- (void)previousPage{
[self dismissViewControllerAnimated:YES completion:nil];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} /*
#pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/ @end
Quartz2D复习(四) --- 图层CALayer和动画CAAnimation的更多相关文章
- 【iOS开发-90】CALayer图层:自己定义图层,图层的一些动画
(1)效果 (2)代码 http://download.csdn.net/detail/wsb200514/8261547 (3)总结 --能够自己定义图层,尤其须要对图片进行圆角裁剪. --图层的动 ...
- [iOS Animation]-CALayer 显示动画
显式动画 如果想让事情变得顺利,只有靠自己 -- 夏尔·纪尧姆 上一章介绍了隐式动画的概念.隐式动画是在iOS平台创建动态用户界面的一种直接方式,也是UIKit动画机制的基础,不过它并不能涵盖所有的动 ...
- 核心动画 CAAnimation 进阶
转载自:http://www.cofcool.net/development/2015/06/20/ios-study-note-nine-CoreAnimation/ Core Animation, ...
- 图层的核心动画(CABaseAnimation)
Main.storyboard // // ViewController.m // 7A14.图层的核心动画 // // Created by huan on 16/2/4. // Copyr ...
- iOS 用CALayer实现动画
与动画有关的几个类的继承关系 涉及到动画的类主要有6个,看一下它们的基本用途: 1. CAAnimation 动画基类 2. CAAnimationGroup 组合多个动画 3. CAPropert ...
- Objective-C 使用核心动画CAAnimation实现动画
先来看看效果吧 整个核心动画就不多做介绍了,随便一搜就能有很多很详细的解释,主要使用以下四种 CABasicAnimation //经典动画 CAKeyframeAnimation //关键帧动画 C ...
- CALayer帧动画
CALayer帧动画 _sunLayer = [[CALayer alloc]init]; _sunLayer.contents = (id)[UIImage imageNamed:@"su ...
- Android中四种补间动画的使用示例(附代码下载)
场景 Android中四种补间动画. 透明度渐变动画 旋转动画 缩放动画 平移动画 注: 博客: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程 ...
- 12.22笔记(关于CALayer//Attributes//CALayer绘制图层//CALayer代理绘图//CALayer动画属性//CALayer自定义子图层//绘图pdf文件//绘图渐变效果)
12.22笔记 pdf下载文件:https://www.evernote.com/shard/s227/sh/f81ba498-41aa-443b-81c1-9b569fcc34c5/f033b89a ...
随机推荐
- Android性能测试工具(一)之Emmagee
Android性能测试工具(一) 之Emmagee Emmagee是监控指定被测应用在使用过程中占用机器的CPU.内存.流量资源的性能测试小工具. 支持SDK:Android2.2以及以上版本 Emm ...
- 【数据压缩】Huffman编码
1. 压缩编码概述 数据压缩在日常生活极为常见,平常所用到jpg.mp3均采用数据压缩(采用Huffman编码)以减少占用空间.编码\(C\)是指从字符空间\(A\)到码字表\(X\)的映射.数据压缩 ...
- OpenJudge4980:拯救行动//stl优先队列
总时间限制: 10000ms 内存限制: 65536kB 描述 公主被恶人抓走,被关押在牢房的某个地方.牢房用N*M (N, M <= 200)的矩阵来表示.矩阵中的每项可以代表道路(@). ...
- 修改cdh5集群中主机节点IP或hostName
前言 在使用cdh集群过程中,难免会因为某些不可抗拒的原因导致节点IP或hostName变动,而cm的监控界面无法完成这些事情,但是cm将集群中所有的主机的信息都存在postgresql数据库的hos ...
- Maven提高篇系列之(五)——处理依赖冲突
这是一个Maven提高篇的系列,包含有以下文章: Maven提高篇系列之(一)——多模块 vs 继承 Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例) ...
- Emit学习(3) - OpCodes - 循环和异常
本来准备直接进入Dapper的, 但是昨天初步看了一下, 内容不少, Dapper不愧是一款成熟的框架, 里面对各种情况的考虑, 很实用, 不过这也使得我短时间内看不完, 所以得等几天了. 那就先来看 ...
- Lua使用心得(1)
这几天研究了一下lua,主要关注的是lua和vc之间的整合,把代码都写好放在VC宿主程序里,然后在lua里调用宿主程序的这些代码(或者叫接口.组件,随便你怎么叫),希望能用脚本来控制主程序的行为.这实 ...
- Learn Spring Framework(continue update...)
Part I. Overview of Spring Framework The Spring Framework is a lightweight(轻量级的) solution and a pote ...
- VS使用WinRAR软件以命令行方式打包软件至一个exe
由于项目需要,需要将一个绿色版软件(即无需在C盘写入文件)发给客户使用,要求是只有一个exe文件,双击即可执行. 网上说WinRAR软件创建自解压文件可以实现,链接http://blog.csdn. ...
- Word, PPT和Excel的常用技巧(持续更新)
本文的目的是记录平时使用Word, PowerPoint和Excel的过程中的一些小技巧,用于提升工作效率. 此文会不定期的更新,更新频率完全取决于实际使用遇到的问题的次数. 目录 Word Powe ...