美文网首页
iOS CoreAnimation(一) - 基础知识

iOS CoreAnimation(一) - 基础知识

作者: 顶级蜗牛 | 来源:发表于2024-03-25 15:55 被阅读0次

    相关文献:
    iOS CoreAnimation(一) - 基础知识
    iOS CoreAnimation(二) - CALayer

    一、了解CoreAnimation

    CPU(Central Processing Unit-中央处理器)是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit)。它由运算器(ALU)和控制器(CU)两大部件组成。此外,还有若干个寄存器和高速缓冲存储器及实现它们之间联系的数据、控制及状态总线。CPU的功能主要是解释计算机指令以及处理计算机软件中的数据。

    cpu

    GPU(Graphics Processing Unit-图形处理器);又称显示核心、显卡、视觉处理器、显示芯片或绘图芯片)是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上图像运算工作的微处理器。GPU不仅在图像处理中应用广泛,还在科学计算、密码破解、数值分析、大数据处理、金融分析等需要并行运算的领域中广为应用。

    GPU

    CoreAnimation是对OpenGL/Metal 与 CoreGraphics进行封装的专门处理图形的一套API接口,简化了图形图像处理需要大量的计算以节约开发者的开发时间。其底层就是让GPU去做事情。

    架构 CoreAnimation分类 核心动画类

    二、UIView与CALayer(视图和图层)

    UIView与CALayer的关系:

    • 1.UIView是UIKit框架中的, 继承于UIRespond,View可以响应触摸事件
      CALayer是QuartzCore框架里面CoreAnimation中的,继承自NSObject, Layer不响应事件
    • 2.UIView有个只读的layer属性,称为根Layer,UIView的图层是由layer来生成的,所以对UIView的frame等属性的修改本质上是对layer的属性的修改。
    • 3.可以给UIView添加子Sublayer,[self.layer addSublayer:],效果像addSubview一样显示,但sublayer在修改position、size、opacity等属性时会产生隐式动画(默认有个动画效果), 这就没有操作subview方便。
    • 4.使用系统提供的layer和自定义layer都可添加为subLayer,但需要调用[layer setNeedsDisplay]。 对于自定义layer方式有三个:设置layer代理、自定义CALayer子类。
    • 5.UIView是根layer的代理。
    view与layer关系

    分工明确:view去相应事件;layer去做显示。

    面试题 面试题

    三、图层树/表示树/渲染树 (Layer Tree / Presentation Tree / Render Tree)

    • 图层树(Layer Tree):包含每一层图层里面对象模型的值(开发者设置的一些值)。

    • 表示树(呈现树Presentation Tree):比如当前动画要发生了,它就包含了当前动画将要显示的值。比如一个layer需要改变颜色,它不会立马更新(隐式动画),需要等待图层树完了之后,表示树才会更新出来。

    所以图层树与表示树之间会有一个滞后性。

    • 渲染树(Render Tree):它使用的是表示树的值,主要对独立的UI渲染动作,每一次渲染都是单独的线程来做事。

    LayerTree -> PresentationTree滞后性的案例:

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        // 平移动画
        CABasicAnimation *animation = [CABasicAnimation animation];
        animation.keyPath = @"position.y";
        animation.toValue = @600;
        animation.duration = 1;
        
        [_redView.layer addAnimation:animation forKey:nil];
    }
    

    执行动画平移完了之后发现redView回到初始的位置。

    解决动画恢复到初始位置:

    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    /**
    KCAFil1ModeForwards:动画结束后,1ayer会一直保持动画最后的状态
    KCAFi11ModeBackwards:在动画开始前,将动画加入一个Layer, layer便立即进入动画的初始状态井等待动画开始.(设置之后就显示动画第一帧)
    kCAFillModeBoth: kCAFillModeForwards & kCAFillModeBackwards
    kCAFil1ModeRemoved: 默认,
    */
    

    四、hitTest

    layer的hitTest

    view的hitTest

    #import "RedView.h"
    @implementation RedView
    /**
     - (UIview*)hitTest: (CGPoint )point withEvent: (UIEvent *)event
     point:在接收器局部坐标系中的点
     event:系统保证调用此方法事简。
     Hit Test 调用顺序
     touch -> UIApplication -> UIWindow -> UIViewController -> UIView -> subview ->... -> 合适的View
     事件的传递顺序刚好和与之相反。
     
     常见UIview 不响应事件的处理有那些?
     1.view.userInteractionEnabled = NO:
     2.view.hidden = yes;
     3.view.alpha < 0.05:
     4. view #BitsuperViewtibounds
     */
    - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        // 1.是否相应时间的必然条件
        if (self.userInteractionEnabled == NO || self.alpha < 0.05 || self.hidden == YES) {
            return  nil;
        }
        // 2,touch的point在self.bounds内容
        if ([self pointInside:point withEvent:event]) {
            for(UIView *subview in self.subviews) {
                // 进行坐标转换
                CGPoint coverPoint = [subview convertPoint: point fromView:self];
                UIView *hittestView = [subview hitTest:coverPoint withEvent:event];
                if (hittestView) {return hittestView;}
            }
            return self;
        }
        return nil;
    }
    @end
    

    注意:常见UIview不响应事件的处理有那些?
    1.view.userInteractionEnabled = NO:
    2.view.hidden = YES;
    3.view.alpha < 0.05:
    4.超出view边界不响应

    HitTest运用场景:

    事件穿透 子视图超出父视图 子视图超出父视图

    五、CoreAnimation简单使用

    #import "ViewController.h"
    /*
     动画添加步骤:
     1.找演员CALayer,确定动画主角
     2.写剧本CAAnimation,规定动画怎么样变换
     3.开拍AddAnimation,开始执行
     */
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIView *redView;
    @property (nonatomic,strong) CALayer *layer;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(100, 100, 100, 100);
        layer.backgroundColor = [UIColor greenColor].CGColor;
        _layer = layer;
        [self.view.layer addSublayer:layer];
    }
    
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //动画1
        CABasicAnimation *animation = [CABasicAnimation animation];
        animation.keyPath = @"position.y";
        animation.toValue = @600;
        animation.duration = 1;
        
        //解决动画恢复到初始位置
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeForwards;
        
        
        [_redView.layer addAnimation:animation forKey:nil];
        
        
        //动画2
        //begin a new transaction
        [CATransaction begin];
        
        //set the animation duration to 1 second
        [CATransaction setAnimationDuration:2.0];
        
        _layer.backgroundColor = [UIColor orangeColor].CGColor;
        
        [CATransaction setCompletionBlock:^{
            //rotate the layer 90 degrees
            CGAffineTransform transform = self.layer.affineTransform;
            transform = CGAffineTransformRotate(transform, M_PI_2);
            self.layer.affineTransform = transform;
            
        }];
        
        //commit the transaction
        [CATransaction commit];
    }
    

    相关文章

      网友评论

          本文标题:iOS CoreAnimation(一) - 基础知识

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