美文网首页
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