iOS开发CoreAnimation解读之二——对CALayer的分析

iOS开发CoreAnimation解读之二——对CALayer的分析

一、UIView中的CALayer属性

1.Layer专门负责view的视图渲染

        每一个UIView的对象中都有一个layer这样的属性,并且layer会负责view中有关图形绘制的相关操作,例如我们设置view的背景颜色和设置layer的背景颜色都是有效的,并且,设置view的背景色依然是通过layer来展示的,我们可以写如下的测试代码:

?


1

2

3

4

5

6

7

    UIView * view = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];

    view.backgroundColor = [UIColor redColor];

     

    UIView * view2 = [[UIView alloc]initWithFrame:CGRectMake(100, 300, 100, 100)];

    view2.layer.backgroundColor = view.layer.backgroundColor;

    [self.view addSubview:view];

    [self.view addSubview:view2];

可以看出,我们设置view的backgroundColor属性其实起作用的也是layer的backgroundColor。

2.自定义view默认layer属性的类

        UIView是很多视图类的父类,根据功能不同,会分出UIImageView,UIScrollerView,UITableView等,CALayer也相似,其也可以根据功能分出许多子类,还可以根据我们的需求自定义一个Layer类。UIView其中的layer默认是CALyer类,我们也可以通过重写View中的如下方法来使其创建我们需要的layer类:

?


1

2

+(Class)layerClass{

}

例如我们自定义一个View类,在自定义一个Layer类,是的自定义的View默认创建的layer是自定义的layer:

在MyView中重写上述方法:

?


1

2

3

+(Class)layerClass{

    return [MyLayer  class];

}

在MyLayer中进行一些自定义:

?


1

2

3

4

5

6

7

8

- (instancetype)init

{

    self = [super init];

    if (self) {

        self.backgroundColor = [UIColor redColor].CGColor;

    }

    return self;

}

之后我们使用这个MyView的对象时,layer层的背景色就是红色的了。

二、几种系统的Layer类

        前边说过,和UIView相似,CALayer也很据功能衍生出许多子类,系统系统给我们可以使用的有如下几种:

1.CAEmitterLayer

CoreAnimation框架中的CAEmitterLayer是一个粒子发射器系统,负责粒子的创建和发射源属性。通过它,我们可以轻松创建出炫酷的粒子效果。

2.CAGradientLayer

CAGradientLayer可以创建出色彩渐变的图层效果,如下:

3.CAEAGLLayer

CAEAGLLayer可以通过OpenGL ES来进行界面的绘制。

4.CAReplicatorLayer

CAReplicatorLayer是一个layer容器,会对其中的subLayer进行复制和属性偏移,通过它,可以创建出类似倒影的效果,也可以进行变换复制,如下:

5.CAScrollLayer

CAScrollLayer可以支持其上管理的多个子层进行滑动,但是只能通过代码进行管理,不能进行用户点按触发。

6.CAShapeLayer

CAShapeLayer可以让我们在layer层是直接绘制出自定义的形状。

7.CATextLayer

CATextLayer可以通过字符串进行文字的绘制。

8.CATiledLayer

CATiledLayer类似瓦片视图,可以将绘制分区域进行,常用于一张大的图片的分不分绘制。

9.CATransformLayer

CATransformLayer用于构建一些3D效果的图层。

三、设置与调整Layer层的内容

设置层的内容有下面三种方式:

1.可以通过设置CGImage为layer的内容。

2.可以通过代理方法来动态修改或者绘制层的内容。

3.通过自定义CALayer对象来创建层的内容。

当你设置了Layer的内容后,例如设置了一张图片,内容的尺寸不一定会刚好和layer的尺寸合适,我们可以对其位置的调整,使其达到我们想要的效果,contentsGravity属性决定了内容对齐与填充方式,它可以分为两个方面:

1.不改变内容的原始大小

这种模式中不会改变内容的原始大小,如果层的尺寸小于内容的尺寸,则内容会被切割,如果层的尺寸大于内容的尺寸,多出的部分将会显示层的背景颜色。下面的这些设置方式为这种模式:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

CA_EXTERN NSString * const kCAGravityCenter

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityTop

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityBottom

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityLeft

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityRight

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityTopLeft

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityTopRight

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityBottomLeft

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityBottomRight

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

每个参数对应的对其模式如下图:

2.改变内容的尺寸大小

这种模式设置的实际上是一种填充方式,参数如下:

?


1

2

3

4

5

6

CA_EXTERN NSString * const kCAGravityResize

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityResizeAspect

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

CA_EXTERN NSString * const kCAGravityResizeAspectFill

    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);

四、CALayer的接口应用总结

1、创建与初始化layer相关

?


1

2

3

4

5

6

//通过类方法创建并初始化一个layer

+ (instancetype)layer;

//初始化方法

- (instancetype)init;

//通过一个layer创建一个副本

- (instancetype)initWithLayer:(id)layer;

2、渲染层layer与模型层layer

    在CALayer中,有如下两个属性,他们都返回一个CALayer的对象:

?


1

2

3

4

//渲染层layer

- (nullable id)presentationLayer;

//模型层layer

- (id)modelLayer;

对于presentationLayer,这个属性不一定总会返回一个实体对象,只有当进行动画或者其他渲染的操作时,这个属性会返回一个在当前屏幕上的layer,不且每一次执行,这个对象都会不同,它是原layer的一个副本presentationLayer的modelLayer就是其实体layer层。

对于modelLayer,它会返回当前的存储信息的Layer,也是当前的layer对象,始终唯一。

3.一些属性与方法

?


1

+ (nullable id)defaultValueForKey:(NSString *)key;

上面这个属性用于设置layer中默认属性的值,我们可以在子类中重写这个方法来改变默认创建的layer的一些属性,例如如下代码,我们创建出来的layer就默认有红色的背景颜色:

?


1

2

3

4

5

6

+(id)defaultValueForKey:(NSString *)key{

    if ([key isEqualToString:@"backgroundColor"]) {

        return (id)[UIColor redColor].CGColor;

    }

    return [super defaultValueForKey:key];

}

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

//这个方法也只使用在子类中重写,用于设置在某些属性改变时是否进行layer重绘

+ (BOOL)needsDisplayForKey:(NSString *)key;

//子类重写这个方法设置属性是否可以被归档

- (BOOL)shouldArchiveValueForKey:(NSString *)key;

/*********************************************/

//设置layer尺寸

@property CGRect bounds;

//设置layer位置

@property CGPoint position;

//设置其在父layer中的层次,默认为0,这个值越大,层次越靠上

@property CGFloat zPosition;

//锚点

@property CGPoint anchorPoint;

//在Z轴上的锚点位置 3D变换时会有很大影响

@property CGFloat anchorPointZ;

//进行3D变换

@property CATransform3D transform;

//获取和设置CGAffineTransform变换

- (CGAffineTransform)affineTransform;

- (void)setAffineTransform:(CGAffineTransform)m;

//设置layer的frame

@property CGRect frame;

//设置是否隐藏

@property(getter=isHidden) BOOL hidden;

//每个layer层有两面,这个属性确定是否两面都显示

@property(getter=isDoubleSided) BOOL doubleSided;

//是否进行y轴的方向翻转

@property(getter=isGeometryFlipped) BOOL geometryFlipped;

//获取当前layer内容y轴方向是否被翻转了

- (BOOL)contentsAreFlipped;

//父layer视图

@property(nullable, readonly) CALayer *superlayer;

//从其父layer层上移除

- (void)removeFromSuperlayer;

//所有子layer数组

@property(nullable, copy) NSArray<CALayer *> *sublayers;

//添加一个字layer

- (void)addSublayer:(CALayer *)layer;

//插入一个子layer

- (void)insertSublayer:(CALayer *)layer atIndex:(unsigned)idx;

//将一个子layer插入到最下面

- (void)insertSublayer:(CALayer *)layer below:(nullable CALayer *)sibling;

//将一个子layer插入到最上面

- (void)insertSublayer:(CALayer *)layer above:(nullable CALayer *)sibling;

//替换一个子layer

- (void)replaceSublayer:(CALayer *)layer with:(CALayer *)layer2;

//对其子layer进行3D变换

@property CATransform3D sublayerTransform;

//遮罩层layer

@property(nullable, strong) CALayer *mask;

//舍否进行bounds的切割,在设置圆角属性时会设置为YES

@property BOOL masksToBounds;

//下面这些方法用于坐标转换

- (CGPoint)convertPoint:(CGPoint)p fromLayer:(nullable CALayer *)l;

- (CGPoint)convertPoint:(CGPoint)p toLayer:(nullable CALayer *)l;

- (CGRect)convertRect:(CGRect)r fromLayer:(nullable CALayer *)l;

- (CGRect)convertRect:(CGRect)r toLayer:(nullable CALayer *)l;

//返回包含某一点的最上层的子layer

- (nullable CALayer *)hitTest:(CGPoint)p;

//返回layer的bounds内是否包含某一点

- (BOOL)containsPoint:(CGPoint)p;

//设置layer的内容,一般会设置为CGImage的对象

@property(nullable, strong) id contents;

//获取内容的rect尺寸

@property CGRect contentsRect;

//设置内容的填充和对其方式,具体上面有说

@property(copy) NSString *contentsGravity;

//设置内容的缩放

@property CGFloat contentsScale;

下面这个属性和内容拉伸相关:

?


1

@property CGRect contentsCenter;

这个属性确定一个矩形区域,当内容进行拉伸或者缩放的时候,这一部分的区域是会被形变的,例如默认设置为(0,0,1,1),则整个内容区域都会参与形变。如果我们设置为(0.25,0.25,0.5,0.5),那么只有中间0.5*0.5比例宽高的区域会被拉伸,四周都不会。

下面这两个属性用来设置缩放或拉伸的模式:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

//设置缩小的模式

@property(copy) NSString *minificationFilter;

//设置放大的模式

@property(copy) NSString *magnificationFilter;

//缩放因子

@property float minificationFilterBias;

//模式参数如下

//临近插值

NSString * const kCAFilterNearest;

//线性拉伸

NSString * const kCAFilterLinear;

//瓦片复制拉伸

NSString * const kCAFilterTrilinear;

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

//设置内容是否完全不透明

@property(getter=isOpaque) BOOL opaque;

//重新加载绘制内容

- (void)display;

//设置内容为需要重新绘制

- (void)setNeedsDisplay;

//设置某一区域内容需要重新绘制

- (void)setNeedsDisplayInRect:(CGRect)r;

//获取是否需要重新绘制

- (BOOL)needsDisplay;

//如果需要,进行内容重绘

- (void)displayIfNeeded;

//这个属性设置为YES,当内容改变时会自动调用- (void)setNeedsDisplay函数

@property BOOL needsDisplayOnBoundsChange;

//绘制与读取内容

- (void)drawInContext:(CGContextRef)ctx;

- (void)renderInContext:(CGContextRef)ctx;

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

//设置背景颜色

@property(nullable) CGColorRef backgroundColor;

//设置圆角半径

@property CGFloat cornerRadius;

//设置边框宽度

@property CGFloat borderWidth;

//设置边框颜色

@property(nullable) CGColorRef borderColor;

//设置透明度

@property float opacity;

//设置阴影颜色

@property(nullable) CGColorRef shadowColor;

//设置阴影透明度

@property float shadowOpacity;

//设置阴影偏移量

@property CGSize shadowOffset;

//设置阴影圆角半径

@property CGFloat shadowRadius;

//设置阴影路径

@property(nullable) CGPathRef shadowPath;

?


1

2

3

4

5

6

7

8

9

10

//添加一个动画对象 key值起到id的作用,通过key值,可以取到这个动画对象

- (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key;

//移除所有动画对象

- (void)removeAllAnimations;

//移除某个动画对象

- (void)removeAnimationForKey:(NSString *)key;

//获取所有动画对象的key值

- (nullable NSArray<NSString *> *)animationKeys;

//通过key值获取动画对象

- (nullable CAAnimation *)animationForKey:(NSString *)key;


时间: 2024-09-09 22:37:29

iOS开发CoreAnimation解读之二——对CALayer的分析的相关文章

iOS开发CoreAnimation解读之三——几种常用Layer的使用解析

iOS开发CoreAnimation解读之三--几种常用Layer的使用解析 一.CAEmitterLayer         CAEmitterLayer是CoreAnimation框架中的粒子发射层,在以前的一片博客中有详细的介绍和范例,这里不再重复,地址如下: 粒子效果的应用和火焰范例:http://my.oschina.net/u/2340880/blog/485095 二.CAGradientLayer         CAGradientLayer是用于色彩梯度展示的layer图层,

iOS开发CoreAnimation解读之一——初识CoreAnimation核心动画编程

iOS开发CoreAnimation解读之一--初识CoreAnimation核心动画编程 一.引言         众所周知,绚丽动画效果是iOS系统的一大特点,通过UIView层封装的动画,基本已经可以满足我们应用开发的所有需求,但若需要更加自由的控制动画的展示,我们就需要使用CoreAnimation框架中的一些类与方法.这里先附上前几篇与动画相关的博客地址,这一系列,我们抽出其中的CoreAnimation框架来详细解读. UIViewAnimation动画的使用:http://my.o

iOS开发CoreAnimation解读之四——Layer层动画内容

iOS开发CoreAnimation解读之四--Layer层动画内容 一.引言         通过前几篇博客的介绍,我们可以了解到layer层可以设置许多与控件UI相关的属性,并且对于iOS开发,UIView层的属性是会映射到CALayer的,因此,可以通过UIKit和CoreAnimation两个框架来设置控件的UI相关属性,当属性发生变化时,我们可以使其展示一个动画效果. 二.CAAnimation动画体系的介绍         CAAnimation是CoreAnimation框架中执行

iOS开发CoreAnimation解读之六——CATransform3D变换的应用

iOS开发CoreAnimation解读之五--CATransform3D变换的应用 一.引言         CATransform3D定义了一个变化矩阵,通过对矩阵参数的设置,我们可以改变layer的一些属性,这个属性的改变,可以产生动画的效果.首先,CATransform3D定义了一个4*4的矩阵,如下: ? 1 2 3 4 5 6 7 struct CATransform3D {   CGFloat m11, m12, m13, m14;   CGFloat m21, m22, m23,

iOS开发CoreAnimation解读之五——高级动画技巧

iOS开发CoreAnimation解读之五--高级动画技巧 一.事务类         CoreAnimation中还有一个非常重要的类:CATransaction事物类,这个可以同时设置多个layer层的动画效果.可以通过隐式和显式两种方式来进行动画操作. 二.CATransaction属性         对layer层的属性操作,都会形成隐式动画,要使用隐式动画,需要关闭layer层的animation动画属性,使用下面的方法: ? 1 2 3 //关闭animation动画效果,开启隐

iOS 开发中 NavigationController经常出现的问题原因分析_IOS

情况一: MyViewController *sampleViewController = [[[MyViewController alloc]initWithXXX] autorelease]; [self.navigationController pushViewController: sampleViewController animated:true]; BUG:界面无反应 分析可能出错的原因: 1:self.navigationController为nil,空指针执行pushViewC

iOS 热更新解读(二)—— JSPatch 源码解析

关于 JSPatch 的实现原理,JSPatch 作者本人 bang 已经有一系列文章阐述: JSPatch 实现原理详解 <一> 核心 JSPatch 实现原理详解 <二> 细节 JSPatch 实现原理详解 <三> 扩展 JSPatch 实现原理详解 <四> 新特性 JSPatch 实现原理详解 <五> 优化 这些文章是对 JSPatch 内部实现原理和细节诸如"require实现"."property实现&qu

iOS开发Swift篇—(二)变量和常量

一.语言的性能 (1)根据WWDC的展示 在进行复杂对象排序时Objective-C的性能是Python的2.8倍,Swift的性能是Python的3.9倍 在实现 RC4加密算法时Objective-C的的性能是Python的127倍,Swift的性能是Python的220倍 有持怀疑态度的国外程序员,也对Objective-C和Swift的性能进行了测试 http://www.splasmata.com/?p=2798 (2)说明 目前的性能不是开发者最需要担心的问题 苹果已经全盘掌握了这个

iOS开发之窥探UICollectionViewController(二) --详解CollectionView各种回调

UICollectionView的布局是可以自己定义的,在这篇博客中先在上篇博客的基础上进行扩充,我们先使用UICollectionViewFlowLayout,然后好好的介绍一下UICollectionView的一些回调方法,主要包括UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UICollectionViewDelegate相关回调方法,并通过实例来介绍每个回调的用法.并且给每个Section添加定制的Header