相关文献:
iOS CoreAnimation(一) - 基础知识
iOS CoreAnimation(二) - CALayer
一、了解CoreAnimation
CPU(Central Processing Unit-中央处理器)
是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit)。它由运算器(ALU)和控制器(CU)两大部件组成。此外,还有若干个寄存器和高速缓冲存储器及实现它们之间联系的数据、控制及状态总线。CPU的功能主要是解释计算机指令以及处理计算机软件中的数据。
GPU(Graphics Processing Unit-图形处理器)
;又称显示核心、显卡、视觉处理器、显示芯片或绘图芯片)是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上图像运算工作的微处理器。GPU不仅在图像处理中应用广泛,还在科学计算、密码破解、数值分析、大数据处理、金融分析等需要并行运算的领域中广为应用。
CoreAnimation
是对OpenGL/Metal 与 CoreGraphics进行封装的专门处理图形的一套API接口,简化了图形图像处理需要大量的计算以节约开发者的开发时间。其底层就是让GPU去做事情。
二、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去做显示。
面试题 面试题三、图层树/表示树/渲染树 (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];
}
网友评论