iOS之核心动画CoreAnimation

核心动画:框架:CoreAnimation
都是基于 CALayer 图层
UIView 视图 -> 可以跟用户交互

图层关系.jpg

CALayer -> 不可以跟用户交互 只能显示内容
UIView ->rootLayer 发生改变 子图层也会发生改变
button 不止有一个视图 改变的只是其中一个视图的rootLayer -> 显示 未被裁切的边框
CALayer 发生改变 子图层 不会跟随发生改变
CALayer ->自带动画效果(当改变属性值的时候)-> 隐示动画

                    bounds 边境范围
                    position 中心点 类似center
                    zPosition z轴中心点
                    anchorPoint 锚点 ✮✮✮✮✮
                      默认锚点 是与中心点重合 
                      链点的最小值是0,0 
                      最大值是 1,1  
                      默认值是0.5,0.5
                      当试图改变的时候  是一链点为基准 去改变

                     锚点的值与位置
                      0.0 = 在图层的左上角
                      0,1 = 左下角
                      1,0 = 右上角
                      1,1 = 右下角
                     计算公式:锚点 = 锚点在视图上的位置.x.y/视图的宽高
 
                    anchorPointZ Z轴锚点
                    transform 转换形态
                    frame NO. Animatable 坐标
                    hidden 隐藏
                    doubleSided 图层背面是否显示
                    geometryFlipped 翻转 颠倒
                    masksToBounds 裁切边境
                    contents 内容  id类型
                    opaque 不透明度
                    allowsEdgeAntialiasing 是否使用 变形后的抗锯齿
                    backgroundColor 背景颜色
                    borderWidth 边框宽
                    borderColor 边框颜色
                    opacity 不透明度
                    shadowColor 阴影颜色
                    shadowOpacity 阴影不透明度
                    rasterizationScale 防止Retina屏幕像素化
                    shadowOffset 阴影偏移量
                    shadowRadius 阴影的半径
     CAAnimation:所有动画的父类,它是一个基类,不能直接使用
1、属性动画:CAPropertyAnimation 基类 -> 通过属性值的改变 产生动画效果
(1) 基础动画(CABasicAnimation)只能是两个点的变化
CASpringAnimation(弹簧动画)
(2)关键帧动画 (CAKeyframeAnimation)可以添加多个点的变化 或者 添加路径
2、动画组:CAAnimationGroup 可以同时添加多种动画 达到预期效果
3、转场动画:CATransition 给视图切换的时候 添加动画效果

CALayer 初始化:两种方式

CALayer *layer = [[CALayer alloc]init]//1
layer = [CALayer layer];//2
layer.frame = CGRectMake(0, 0, 100, 100);
    //    设置图层拐角的半径
    //    半径是 宽度的一半
    layer.cornerRadius = 100/2;

    layer.backgroundColor = [UIColor brownColor].CGColor;
    
    [self.view.layer addSublayer:layer];
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    UITouch *touch = [touches anyObject];
    
    
    layer.position = [touch locationInView:self.view];
    CGFloat width = CGRectGetWidth(layer.bounds)!=100 ? 100:25;
    layer.bounds = CGRectMake(0, 0, width, width);
    CGColorRef color = [UIColor brownColor].CGColor != layer.backgroundColor ? [UIColor brownColor]
    .CGColor:[UIColor colorWithRed:1.000 green:0.183 blue:0.715 alpha:1.000].CGColor;
    
    layer.backgroundColor = color;
    layer.cornerRadius = layer.cornerRadius != 50 ? 50:0; layer.opacity = 0.2;  
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    layer.opacity = 1.0;
}

如图:

EAF24432-07BB-49EB-B1AA-0954C0C21203.png
08C46804-F2DD-41F4-88B5-9635ECEF30E5.png

下面利用锚点设置:

#import "ViewController.h"
#define Angle(a)(a)*M_PI/180
#define sAngle 6 //每秒的度数
// sAngle*N秒*M_PI/180
@interface ViewController ()
{
    CALayer *layer;
}
@property (nonatomic,strong)CALayer *pointLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
 UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetWidth(self.view.bounds))];
    UIImage *image = [UIImage imageNamed:@"biaopan"];
    imageView.image = image;
    imageView.center = self.view.center;
    [self.view addSubview:imageView];
//    CALayer 初始化
//    添加到父视层 addSubLayer:
    
//    CALayer *layer = [[CALayer alloc]init]
    layer = [CALayer layer];
    layer.frame = CGRectMake(0, 0, 100, 100);
    //    设置图层拐角的半径
    //    半径是 宽度的一半
    layer.cornerRadius = 100/2;

    layer.backgroundColor = [UIColor brownColor].CGColor;
    
    [self.view.layer addSublayer:layer];
    
//    图层 不能跟用户交互 不可以添加响应事件
    
    NSLog(@"%@",self.pointLayer);
    
    
//    改变锚点
    self.pointLayer.anchorPoint = CGPointMake(0.5, 0.9);
    self.pointLayer.contents = (id)[UIImage imageNamed:@"shizhen"].CGImage;
    
    
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(start) userInfo:nil repeats:YES];
    
}
-(void)start{
//    NSCalendar 日历表 可以通过日历类 获得到 年月日 时分秒
//    NSCalendar 日历
//    NSDateComponents 组件
    
//    当前的日历
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents
//    components:需要的组件类型
//    fromDate:获得哪个日期的 组件
    *components =[calendar components:NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:[NSDate date]];
    float s = components.second * sAngle;
//    Angle(s)
    self.pointLayer.transform = self.pointLayer.transform = CATransform3DMakeRotation(Angle(s), 0, 0, 1);
    
    
}
-(CALayer *)pointLayer{
    if (_pointLayer) {
        return _pointLayer;
    }
    _pointLayer = [CALayer layer];
    _pointLayer.bounds = CGRectMake(0, 0, 29, 236);
    _pointLayer.position = self.view.center;
    _pointLayer.backgroundColor = [UIColor whiteColor].CGColor;
    [self.view.layer addSublayer:_pointLayer];
    return _pointLayer;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  
//    锚点
//    self.view.transform = 
//    self.pointLayer.transform  CATransform
//    旋转
    self.pointLayer.transform = CATransform3DMakeRotation(Angle(60), 0, 0, 1);
    
    
    
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  
    //还原的方法
    self.pointLayer.transform = CATransform3DIdentity;
}
8CB0E9F8-502F-4199-8E77-FCC7E153054D.png
536AF7A2-EAF8-4B9E-95F6-13E52EA44EFF.png

这样就设计了一个相当于时钟的秒针。

粒子发送器图层

CAEmitterLayer:发送器
birthRate 每秒发送粒子的数量
 emittermode:发送的样式
kCAEmitterLayerPoints  默认点的形式发送
kCAEmitterLayerOutline 线的形式
kCAEmitterLayerSurface 面的形式
kCAEmitterLayerVolume 团的形式

emitterShape:发送形状的样式
kCAEmitterLayerPoint 点
kCAEmitterLayerLine 线
kCAEmitterLayerRectangle 矩形
kCAEmitterLayerCuboid  立方体
kCAEmitterLayerCircle 曲线
kCAEmitterLayerSphere 球体

rendermode:粒子出现的样式
 kCAEmitterLayerOldestFirst 最后的出生的粒子 在第一个
 kCAEmitterLayerOldestLast 最后的出生的粒子 在最后面
 kCAEmitterLayerBackToFront 把后面的 放到上面
 kCAEmitterLayerAdditive 叠加
 emitterCells;在粒子发生器上面 添加粒子
 
 CAEmitterCell:粒子
   contents:粒子的内容
  lifttime:存活时间
  lifttimeRange:存活时间的范围
  birthRate:每秒粒子生成的数量
emissionLatitude:散发的纬度(方向)->弧度->上下
 emissionLongitude:散发的经度(方向)->弧度->左右
velocity:发送的速度 -> 速度越快越远
  xAcceleration:X轴的加速度 惯性 动力
 yAcceleration:Y轴的加速度
 zAcceleration:Z轴的加速度
 emissionRange:散发的范围 -> 弧度 ->范围
 name:粒子的名字  可以通过名字 找到粒子

案例:
先声明一个属性:

@property (nonatomic,strong)CAEmitterLayer *emitterLayer;
self.emitterLayer.frame = CGRectMake(100, 100, 200, 200);
   
//    设置粒子发送器 每秒钟 发送粒子的 数量
  self.emitterLayer.birthRate = 1;
//    设置 粒子发送器的样式
  self.emitterLayer.renderMode = kCAEmitterLayerAdditive;
  
  //初始化
  CAEmitterCell *cell  =[CAEmitterCell emitterCell];
  cell.contents = (id)[UIImage imageNamed:@"2"].CGImage;
  //粒子的出生量
  cell.birthRate = 3;
  //存活时间->秒
  cell.lifetime = 5;
  
  //发送速度
  cell.velocity = 50;
  //设置粒子发送的 方向
  cell.emissionLatitude = 90*M_PI/180;
//    发送粒子的加速度
  cell.yAcceleration = 100;
  
//    把粒子的cell添加到 粒子发送器
  self.emitterLayer.emitterCells = @[cell];
      
}
//懒加载
-(CAEmitterLayer *)emitterLayer{
  if (_emitterLayer) {
      return _emitterLayer;
      
  }
  _emitterLayer = [CAEmitterLayer layer];
  [self.view.layer addSublayer:_emitterLayer];
  return _emitterLayer;
}
粒子发送器图层.png

渐变图层
CAGradientLayer 渐变图层
colors:渐变颜色的数组 -> id ->CGColor
locations: 颜色渐变的 百分比 数组
startPoint 颜色渐变的起始点
endPoint 颜色渐变的终点
颜色会根据 设置的两个点 去变化

 self.view.backgroundColor = [UIColor blackColor];
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetWidth(self.view.frame))];
    UIImage *img = [UIImage imageNamed:@"5.gif"];
    imageView.image = img;
    imageView.center = self.view.center;
    [self.view addSubview:imageView];


CAGradientLayer *layer = [CAGradientLayer layer];
    layer.frame = self.view.frame;
    layer.colors = @[(id)[UIColor greenColor].CGColor,(id)[UIColor blueColor].CGColor,(id)[UIColor colorWithRed:0.202 green:0.760 blue:1.000 alpha:1.000].CGColor];
    layer.opacity = 0.7;//透明度
    layer.startPoint = CGPointMake(0, 0);
    layer.endPoint = CGPointMake(1, 1);
    layer.locations = @[@0.2,@0.6,@0.2];
    [self.view.layer addSublayer:layer];

渐变图层.png

复制图层
首先要建一个继承与UIView的类 ,因为要想复制视图的图层,就必须 重写视图的layerClass

#import "CanReplicatorView.h"

@implementation CanReplicatorView
//要想复制视图的图层 就必须 重写视图的layerClass
//错误 -[CALayer setInstanceCount:]: unrecognized selector sent to instance 0x7fb111698450

+(Class)layerClass{
    return [CAReplicatorLayer class];
}

@end
CanReplicatorView *view = [[CanReplicatorView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:view];
    
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    UIImage *img = [UIImage imageNamed:@"4"];
    imageView.image = img;
//    imageView.center = self.view.center;
    [view addSubview:imageView];
    
//    instanceCount :layer的实例化数量
//    instanceTransform:复制图层的变形的方法
//    transform:原有图层变形的方法
    
    CAReplicatorLayer *layer = (CAReplicatorLayer *)view.layer;
//    instanceCount :layer的实例化数量
    layer.instanceCount = 2;
//    改变复制图层 的 样式
    CATransform3D transform = CATransform3DMakeTranslation(0, 80, 0);
    layer.instanceTransform = CATransform3DRotate(transform, 180*M_PI/180, 1, 0, 0);
    layer.instanceRedOffset = -0.2;
    layer.instanceBlueOffset = -0.2;
    layer.instanceGreenOffset = -0.2;
    layer.instanceAlphaOffset = -0.4;
    
}
复制图层.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容