CAAnimation

作者: 纳兰怮翌 | 来源:发表于2019-08-09 11:55 被阅读0次
  • CALayer

*为什么要将UIView与CALayer 分开
避免重复代买mac os 和iOS交互手段不一样,所以要分开


6F40C7C0-DC7C-40D3-8AF2-0CEBE3D5723F.png

Layer-Tree Presentation-Tree 呈现树
Reader-Tree(Private) 渲染树

  • CABasicAnimation

移动的不是视图本身(隐藏),而是移动的是Presentation图层,在移动结束的时候消失

//动画结束后,layer会一直保持动画最后的状态
CA_EXTERN CAMediaTimingFillMode const kCAFillModeForwards
//在动画开始前,只要将动画加入一个layer,layer便立即进入动画的初始状态并等到动画开始
CA_EXTERN CAMediaTimingFillMode const kCAFillModeBackwards
//kCAFillModeForwards 和kCAFillModeBackwards组合
CA_EXTERN CAMediaTimingFillMode const kCAFillModeBoth
//默认,
CA_EXTERN CAMediaTimingFillMode const kCAFillModeRemoved
  • CATransaction (隐视动画)
    默认动画时长为:0.25s,通过runloop执行
    *CALayer 常用属性 - contents
UIImage *image = [UIImage imageNamed:@"test.png"];
    self.view.layer.contents = (__bridge id)image.CGImage;
self.view.layer.contentsGravity = kCAGravityResizeAspectFill;
    self.view.contentMode = UIViewContentModeScaleAspectFill;
//CALayer 常用属性 - contentsScale
self.view.layer.contentsScale = [[UIScreen mainScreen]scale];

*CALayer 常用属性 - contentsRect
*CALayer 常用属性 - ZPosition (深度缓存区)
*CALayer 常用属性 - Hit Testing
hit test调用顺序
hit test -> UIApplication ->UIWindow -> UIViewController -> UIView -> UISubView -> ...
事件的传递顺序与之相反
常见UIView不响应事件的处理有哪些
1.view.userInteractionEnabled = NO;
2.view.hidden = YES;
3.view.alpha < 0.05;
4.view 超过superView的bounds;

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *blueView;
@property (strong, nonatomic) CALayer *layer;
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _layer = [CALayer layer];
    _layer.frame = CGRectMake(0, 0, 30, 30);
    _layer.backgroundColor = [UIColor greenColor].CGColor;
    [_blueView.layer addSublayer:_layer];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    CGPoint point = [[touches anyObject]locationInView:self.view];
    CALayer *layer = [self.view.layer hitTest:point];
    if (layer == self.layer){
        NSLog(@"layer.....");
    }else if (layer == self.blueView.layer){
        NSLog(@"blueView.layer...");
    }else{
        NSLog(@"self.view.layer....");
    }
}
  • CALayer -- 仿射变换


    DB1A03F6-8591-4D08-B46B-147AE4E4EDD6.png
//沿y轴旋转90°
CATransform3D transform3D = CATransform3DIdentity;
    transform3D.m34 = -1.0/500.0;
    transform3D = CATransform3DRotate(transform3D, M_PI_4, 1, 1, 1);
    _iconImageView.layer.transform = transform3D;
//正背面渲染 --> 渲染技术正背面剔除,判断用户可见/不可见,layer在旋转180°之后的一个正背面渲染是否可见的操作
_iconImageView.layer.doubleSided = NO;
//在一个父亲视图中有两个子视图的旋转 23CE5ECD-7515-4406-9FEC-40724031273C.png
//CATransform3D画立体的正方体,xib中的view的大小为(100,100)
@interface SeconedViewController ()
@property (strong, nonatomic) IBOutlet UIView *view0;
@property (strong, nonatomic) IBOutlet UIView *view1;
@property (strong, nonatomic) IBOutlet UIView *view2;
@property (strong, nonatomic) IBOutlet UIView *view3;
@property (strong, nonatomic) IBOutlet UIView *view4;
@property (strong, nonatomic) IBOutlet UIView *view5;
@property (strong, nonatomic)NSArray *array;

@end

@implementation SeconedViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _array = @[_view0,_view1,_view2,_view3,_view4,_view5];
    CATransform3D transform3D = CATransform3DIdentity;
    transform3D.m34 = -1.0/500.0;
    self.view.layer.sublayerTransform = CATransform3DRotate(transform3D, -M_PI_4, 1, 1,0);
    //面对用户的view
    CATransform3D transform0 = CATransform3DMakeTranslation(0, 0, 50);
    [self addFace:0 withTransform:transform0];
    //顶部的view
    CATransform3D transform1 = CATransform3DMakeTranslation(0, -50, 0);
    transform1 = CATransform3DRotate(transform1, M_PI_2, 1,0, 0);
    [self addFace:1 withTransform:transform1];
    CATransform3D transform2 = CATransform3DMakeTranslation(50, 0, 0);
    transform2 = CATransform3DRotate(transform2, -M_PI_2, 0, 1, 0);
    [self addFace:2 withTransform:transform2];
    CATransform3D transform3 = CATransform3DMakeTranslation(0, 0, -50);
    [self addFace:4 withTransform:transform3];
}
- (void)addFace:(NSInteger)index withTransform:(CATransform3D)transform{
    UIView *view = _array[index];
    [self.view addSubview:view];
    CGRect rect = self.view.bounds;
    view.center = CGPointMake(rect.size.width/2.0, rect.size.height/2.0);
    view.layer.transform = transform;
}

*CAShaperLayer

//画火柴人
UIBezierPath *path = [UIBezierPath new];
    [path addArcWithCenter:CGPointMake(100, 100) radius:50.0 startAngle:0 endAngle:2*M_PI clockwise:YES];
    [path moveToPoint:CGPointMake(100, 150)];
    [path addLineToPoint:CGPointMake(100, 300)];
    [path moveToPoint:CGPointMake(100, 170)];
    [path addLineToPoint:CGPointMake(60, 200)];
    [path moveToPoint:CGPointMake(100, 170)];
    [path addLineToPoint:CGPointMake(140, 200)];
    [path moveToPoint:CGPointMake(100, 300)];
    [path addLineToPoint:CGPointMake(60, 330)];
    [path moveToPoint:CGPointMake(100, 300)];
    [path addLineToPoint:CGPointMake(140, 330)];
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    //画笔的颜色
    shapeLayer.strokeColor = [UIColor redColor].CGColor;
    //填充色
    shapeLayer.fillColor = [UIColor whiteColor].CGColor;
    //画笔的宽度
    shapeLayer.lineWidth = 5;
    //连接方式
    shapeLayer.lineJoin = kCALineJoinRound;
    shapeLayer.lineCap = kCALineCapRound;
    shapeLayer.path = path.CGPath;
    [self.view.layer addSublayer:shapeLayer];

//切圆角


WeChat1b1479b45fcf4dad35de99d530411ef0.png
  • CATextLayer
CATextLayer *textLayer = [CATextLayer layer];
    textLayer.frame = CGRectMake(10, 100, self.view.frame.size.width-20, 100);
    [self.view.layer addSublayer:textLayer];
    //设置文字颜色
    textLayer.foregroundColor = [UIColor redColor].CGColor;
    //设置对齐方式
    textLayer.alignmentMode = kCAAlignmentLeft;
    //环绕
    textLayer.wrapped = YES;
    //Retina屏幕像素渲染
    textLayer.contentsScale = [UIScreen mainScreen].scale;
    //设置字体
    UIFont *font = [UIFont systemFontOfSize:15];
    CFStringRef fontName = (__bridge CFStringRef)font.fontName;
    CGFontRef fontRef = CGFontCreateWithFontName(fontName);
    textLayer.font = fontRef;
    textLayer.fontSize = font.pointSize;
    //释放
    CGFontRelease(fontRef);
    textLayer.string = @"测试,啦啦啦啦啦啦";
  • CATransformLayer
- (void)viewDidLoad {
    [super viewDidLoad];
    CATransform3D transform3D  =  CATransform3DIdentity;
    transform3D.m34 = -1.0/500.0;
    self.view.layer.sublayerTransform = CATransform3DRotate(transform3D, -M_PI_4, 1, 1, 0);
    [self.view.layer addSublayer:[self addTransform]];
}
- (CALayer *)addTransform{
    CATransformLayer *transformLayer = [CATransformLayer layer];
    CATransform3D transform0 = CATransform3DMakeTranslation(0, 0, 50);
    [transformLayer addSublayer:[self createLayer:transform0]];
    CATransform3D transform1 = CATransform3DMakeTranslation(0, -50, 0);
    transform1 = CATransform3DRotate(transform1, -M_PI_2, 1, 0, 0);
    [transformLayer addSublayer:[self createLayer:transform1]];
    CATransform3D transform2 = CATransform3DMakeTranslation(50, 0, 0);
    transform2 = CATransform3DRotate(transform2, M_PI_2, 0, 1, 0);
    [transformLayer addSublayer:[self createLayer:transform2]];
    CGSize containerSize = self.view.bounds.size;
    transformLayer.position = CGPointMake(containerSize.width/2.0, containerSize.height/2.0);
    return transformLayer;
}
- (CALayer *)createLayer:(CATransform3D)transform{
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(0, 0, 100, 100);
    CGFloat read = (rand()/(double)INT_MAX);
    CGFloat green = (rand()/(double)INT_MAX);
    CGFloat blue = (rand()/(double)INT_MAX);
    layer.backgroundColor = [UIColor colorWithRed:read green:green blue:blue alpha:1.0].CGColor;
    layer.transform = transform;
    return layer;
}
  • CAGradientLayer
CAGradientLayer  *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = CGRectMake(10, 120, self.view.frame.size.width - 20, 100);
    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,(__bridge id)[UIColor greenColor].CGColor,(__bridge id)[UIColor blueColor].CGColor];
    //设置颜色的的占比
    gradientLayer.locations = @[@0.01,@0.79,@0.2];
    //开始位置
    gradientLayer.startPoint = CGPointMake(0, 0);
    //结束位置
    gradientLayer.endPoint = CGPointMake(1, 1);
    [self.view.layer addSublayer:gradientLayer];
  • CARelicatorLayer
CAReplicatorLayer *layer = [CAReplicatorLayer layer];
    //设置复制层中的总层数,包含原生层
    layer.instanceCount = 2;
    CATransform3D transform3D  = CATransform3DIdentity;
    //间隔
    CGFloat number = _IconImageView.bounds.size.height + 2;
    transform3D = CATransform3DTranslate(transform3D, 0, number, 0);
    transform3D = CATransform3DScale(transform3D, -1, -1, 0);
    layer.instanceTransform = transform3D;
    //修改t透明度
    layer.instanceAlphaOffset = -0.75;
  • CAEmitterLayer&CAEmitterCell
#import "NinthViewController.h"

@interface NinthViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelTopLayout;
@property (nonatomic, strong)CAEmitterLayer *layer;
@end

@implementation NinthViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    if(UIApplication.sharedApplication.statusBarFrame.size.height > 20){
        _labelTopLayout.constant = 88;
    }
    //1.创建发射源
    CAEmitterLayer *layer = [CAEmitterLayer layer];
    [self.view.layer addSublayer:layer];
    _layer = layer;
    //发射源尺寸
    layer.emitterSize = self.view.frame.size;
    //发射源的形状
    layer.emitterShape = kCAEmitterLayerPoint;
    //发射模式
    layer.emitterMode = kCAEmitterLayerPoints;
    //l粒子发射的中心点
    layer.emitterPosition = CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height);
    //2.设置cell(粒子的样式)
    CAEmitterCell *cell = [CAEmitterCell emitterCell];
    cell.name = @"cell";
    //粒子的产生率
    cell.birthRate = 20.0f;
    //粒子的生命周期
    cell.lifetime = 10.0f;
    //粒子速度
    cell.velocity = 40.0f;
    cell.velocityRange = 100.0;
    //在y轴上面的加速度
    cell.yAcceleration = -15.0f;
    //发射的范围
    cell.emissionLatitude = 0;
    cell.emissionRange = M_PI;
    //缩放
    cell.scale = 0.2;
    cell.scaleRange = 0.1;
    cell.scaleSpeed = 0.02;
    //粒子的内容
    cell.contents =(id)[[UIImage imageNamed:@"yuandian"]CGImage];
    //颜色变化
    cell.color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0].CGColor;
    //粒子颜色改变范围
    cell.alphaRange = 0.8;
    cell.redRange = 1.0f;
    cell.greenRange =1.0f;
    //粒子变化的速度
    cell.blueSpeed = 1.0f;
    cell.alphaRange = -0.1f;
    layer.emitterCells = @[cell];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    CGPoint point = [self loacationFromTouchEvent:event];
    [self setBallInPsition:point];
}
- (CGPoint)loacationFromTouchEvent:(UIEvent *)event{
    UITouch *touch = [[event allTouches]anyObject];
    return [touch locationInView:self.view];
}
- (void)setBallInPsition:(CGPoint)position{
    //粒子放大过程
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"emitterCells.cell.scale"];
    animation.fromValue = @0.2;
    animation.toValue = @0.5;
    animation.duration = 1.0;
    //线性变化
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    //移动粒子的发射位置
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    [_layer addAnimation:animation forKey:nil];
    [_layer setValue:[NSValue valueWithCGPoint:position] forKey:@"emitterPosition"];
    [CATransaction commit];
}
@end

//下雨的效果

#import "TenViewController.h"
@interface TenViewController ()
@property (nonatomic, strong)CAEmitterLayer *layer;
@end

@implementation TenViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createRainLayer];
}
- (void)createRainLayer{
    //创建发射源
    CAEmitterLayer *layer = [CAEmitterLayer layer];
    _layer  = layer;
    [self.view.layer addSublayer:layer];
    //发射中心
    layer.emitterPosition = CGPointMake(self.view.bounds.size.width/2.0+20, -10);
    //设置发射属性
    layer.emitterShape = kCAEmitterLayerLine;
    layer.emitterMode = kCAEmitterLayerLine;
    //发射源尺寸
    layer.emitterSize = self.view.frame.size;
    //创建发射粒子
    CAEmitterCell *cell = [CAEmitterCell emitterCell];
    //设置粒子图片背景
    cell.contents = (id)[[UIImage imageNamed:@"rain"]CGImage];
    //设置粒子产生率
    cell.birthRate = 80.0f;
    //设置粒子生命周期
    cell.lifetime = 20.0f;
    //设置粒子的加速度
    cell.speed = 1.0f;
    //设置粒子速度
    cell.velocity = 10.0f;
    cell.velocityRange = 10.0f;
    //设置粒子在y轴上面的加速度
    cell.yAcceleration = 100;
    //设置粒子的缩放
    cell.scale = 0.1;
    layer.emitterCells = @[cell];
}
//开始或者停止下雨
- (IBAction)beginRainButtonClick:(UIButton *)sender {
    if (sender.selected) {
        NSLog(@"开始下雨");
        [sender setTitle:@"开始下雨" forState:UIControlStateNormal];
        [_layer setValue:@1.0f forKey:@"birthRate"];
    }else{
        NSLog(@"停止下雨");
        [sender setTitle:@"停止下雨" forState:UIControlStateNormal];
        [_layer setValue:@0.0f forKey:@"birthRate"];
    }
    sender.selected = ! sender.selected;
}
//下大雨
- (IBAction)BigRainButtonClick:(UIButton *)sender {
    float rate = 1;
    float scale = 0.1;
    if (_layer.birthRate <= 80 ){
        [_layer setValue:@(_layer.birthRate + rate) forKey:@"birthRate"];
        [_layer setValue:@(_layer.scale + scale) forKey:@"scale"];
    }
}
//下小雨
- (IBAction)SamllRainButtonClick:(UIButton *)sender {
    float rate = 1;
    float scale = 0.1;
    if (_layer.birthRate >= 1 ){
        [_layer setValue:@(_layer.birthRate - rate) forKey:@"birthRate"];
        [_layer setValue:@(_layer.scale - scale) forKey:@"scale"];
    }
}
@end

相关文章

网友评论

    本文标题:CAAnimation

    本文链接:https://www.haomeiwen.com/subject/marxhctx.html