CALayer

1.CALayer和UIView的区别

(1)UIView是UIKit的(只能iOS使用),CALayer是QuartzCore的(iOS和mac os通用)。

(2)UIView继承UIResponder,CALayer继承NSObject,UIView比CALayer多了一个事件处理的功能,也就是说,CALayer不能处理用户的触摸事件,而UIView可以。

(3)UIView来自CALayer,是CALayer的高层实现和封装,UIView的所有特性来源于CALayer支持。

(4)CABasicAnimation,CAAnimation,CAKeyframeAnimation等动画类都需要加到CALayer上。

 

2.CALayer

 

 

3.CALayer属性

属性

说明

是否支持隐式动画

anchorPoint

和中心点position重合的一个点,称为“锚点”,锚点的描述是相对于x、y位置比例而言的默认在图像中心点(0.5,0.5)的位置

backgroundColor

图层背景颜色

borderColor

边框颜色

borderWidth

边框宽度

bounds

图层大小

contents

图层显示内容,例如可以将图片作为图层内容显示

contentsRect

图层显示内容的大小和位置

cornerRadius

圆角半径

doubleSided

图层背面是否显示,默认为YES

frame

图层大小和位置,不支持隐式动画,所以CALayer中很少使用frame,通常使用bounds和position代替

hidden

是否隐藏

mask

图层蒙版

maskToBounds

子图层是否剪切图层边界,默认为NO

opacity

透明度 ,类似于UIView的alpha

position

图层位置

shadowColor

阴影颜色

shadowOffset

阴影偏移量

shadowOpacity

阴影透明度,注意默认为0,如果设置阴影必须设置此属性

shadowPath

阴影的形状

shadowRadius

阴影模糊半径

sublayers

子图层

sublayerTransform

子图层形变

transform

图层形变

 

4.CALayer层的属性:position(位置) 和 anchorPoint (锚点)

 

(1)简单介绍

CALayer有2个非常重要的属性:position 和 anchorPoint

 

@property CGPoint position;

用来设置CALayer在父层中的位置

以父层的左上角为原点(0, 0)

 

@property CGPoint anchorPoint;

称为“定位点”、“锚点”

决定着`CALayer上的哪个点`会与`position属性表示的点`重合

anchorPoint的坐标轴以CALayer的左上角为原点(0, 0),它的x、y取值范围都是0~1,默认值为(0.5, 0.5)

 

(2)图示

anchorPoint

它的取值为0~1

211042080984913.png

 

 

红色图层的anchorPoint为(0,0)

211043516923761.png

 

 

红色图层的anchorPoint为(0.5,0.5)

211044422544943.png

 

 

红色图层的anchorPoint为(1,1)

211045295362120.png

 

 

红色图层的anchorPoint为(0.5,0)

211046325041425.png

 

 

positionanchorPoint

添加一个红色图层到绿色图层上,红色图层显示到什么位置,由position属性决定

  假设红色图层的position是(100,100)

  到底把红色图层的哪个点移动到(100,100)的坐标位置,由锚点确定的。

 

  红色图层的锚点是(0,0)

211050062546726.png

 

 

红色图层的锚点是(0.5,0.5)

211051150514077.png

 

 

红色图层的锚点是(1,1)

211052237399927.png

 

 

红色图层的锚点是(0.5,0)

211053412391271.png

 

(3)代码

- (void)positionAndAnchorPoint
{
    CALayer *layer = [CALayer layer];
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor redColor].CGColor;
    //位置
    layer.position = CGPointMake(100, 100);
    //锚点(0<= x,y <= 1.0)
    layer.anchorPoint = CGPointMake(0.5, 0.5);
    [self.view.layer addSublayer:layer];

}

 

 

5.图层内容和内容模式

 

内容:默认为空,一般为CGImageRef类型

@property(nullable, strong) id contents;

/* An object providing the contents of the layer, typically a CGImageRef,

 * but may be something else. (For example, NSImage objects are

 * supported on Mac OS X 10.6 and later.) Default value is nil.

 * Animatable. */

 

内容模式:图片会压缩变形,需要设置内容的模式 

@property(copy) NSString *contentsGravity;

/* A string defining how the contents of the layer is mapped into its

 * bounds rect. Options are `center', `top', `bottom', `left',

 * `right', `topLeft', `topRight', `bottomLeft', `bottomRight',

 * `resize', `resizeAspect', `resizeAspectFill'. The default value is

 * `resize'. Note that "bottom" always means "Minimum Y" and "top"

 * always means "Maximum Y". */

 

/**  Layer `contentsGravity' values.

kCAGravityCenter

kCAGravityTop

kCAGravityBottom

kCAGravityLeft

kCAGravityRight

kCAGravityTopLeft

kCAGravityTopRight

kCAGravityBottomLeft

kCAGravityBottomRight

kCAGravityResize

kCAGravityResizeAspect

kCAGravityResizeAspectFill

 **/

 

- (void)contentAndContentMode
{
    CALayer *layer = [CALayer layer];
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor lightGrayColor].CGColor;

    //位置
    layer.position = CGPointMake(100, 100);
    NSLog(@"%@",NSStringFromCGRect(layer.frame));

    //设置内容
    layer.contents = (id)[UIImage imageNamed:@"c75c10385343fbf2c6e17e6eb27eca8064388faa"].CGImage;

    //图片会压缩变形,需要设置内容的模式
    //内容的模式,和UIImageView里面的contentMode相似
    layer.contentsGravity = kCAGravityResizeAspect;
    [self.view.layer addSublayer:layer];
}

 

 

 

6.图片添加阴影 和 阴影路径(CGMutablePathRef)

 添加阴影

  注意:layer.shadowOpacity 默认值为 0 ,即阴影默认是透明的。设置为 1 才显示引用。

- (void)shadow
{
    CALayer *layer = [CALayer layer];
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor lightGrayColor].CGColor;
    //位置
    layer.position = CGPointMake(100, 100);
    
    //阴影颜色
    layer.shadowColor = [UIColor redColor].CGColor;
    //阴影半径
    layer.shadowRadius = 2;
    //阴影偏移
    layer.shadowOffset = CGSizeMake(30, 30);
    //阴影是否是不透明,1表示不透明(默认是0)
    layer.shadowOpacity = 1.0;
    
    [self.view.layer addSublayer:layer];
    

    //创建阴影的路径
    CGMutablePathRef path = CGPathCreateMutable();
#if 0
    //添加圆弧路径
    CGPathAddArc(path, NULL, 50, 50, 100, 0, M_PI * 2, YES);
#endif
    //添加方形路径
    CGPathAddRect(path, NULL, CGRectMake(0, 0, 200, 200));
    //设置阴影路径
    layer.shadowPath = path;
}

 

 

 

7.剪切超过父图层的部分

- (void)clip
{
    CALayer *l1 = [CALayer layer];
    l1.bounds = CGRectMake(0, 0, 100, 100);
    l1.backgroundColor = [UIColor lightGrayColor].CGColor;
    l1.position = CGPointMake(100, 100);
    [self.view.layer addSublayer:l1];
    
    //剪切超过父图层的部分
    l1.masksToBounds = YES;
    
    CALayer *l2 = [CALayer layer];
    l2.bounds = CGRectMake(0, 0, 100, 100);
    //位置
    l2.position = CGPointMake(100, 100);
    l2.backgroundColor = [UIColor purpleColor].CGColor;
    
    [l1 addSublayer:l2];
}

 

 

 

8.图片添加边框和圆角

 边框宽度默认为0,设置完颜色要记得设置宽度

 

- (void)border
{
    CALayer *l = [CALayer layer];
    l.bounds = CGRectMake(0, 0, 100, 100);
    l.backgroundColor = [UIColor lightGrayColor].CGColor;
    l.position = CGPointMake(100, 100);
    //边框颜色
    l.borderColor = [UIColor redColor].CGColor;;
    //边框宽度
    l.borderWidth = 3;
    //圆角半径
    l.cornerRadius = 20;
    [self.view.layer addSublayer:l];
}

 

 

 

9.剪切图片的一部分

 通过设置 layer.contentsRect 来截取出图片的一部分

 contentsRect:

/* A rectangle in normalized image coordinates defining the subrectangle of the `contents' property that will be drawn into the layer.

* If pixels outside the unit rectangles are requested, the edge pixels of the contents image will be extended outwards.

*  If an empty rectangle is provided, the results are undefined. 

* Defaults to the unit rectangle [0 0 1 1]. Animatable. */

  

- (void)clipSome
{
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(100, 100, 200, 200);
    layer.contents = (id)[UIImage imageNamed:@"20101116120457-1388528443"].CGImage;
    [self.view.layer addSublayer:layer];
    
    //把一个图片切成多块
    for (int i = 0; i < 9; i++)
    {
        CALayer *l = [CALayer layer];
        l.frame = CGRectMake(50 + 90*(i%3), 350 + 90*(i/3), 80, 80);
        l.contents = (id)[UIImage imageNamed:@"20101116120457-1388528443"].CGImage;
        //设置内容的大小
        l.contentsRect = CGRectMake(1.0/3.0*(i%3), 1.0/3.0*(i/3), 1.0/3.0, 1.0/3.0);
        l.backgroundColor = [UIColor redColor].CGColor;
        [self.view.layer addSublayer:l];
    }
}

 

 

10.仿射变换

 layer中的仿射变换与label中的类似:

    UILabel *l;                    对应 layer

    l.transform           ---->  CGAffineTransform

    l.affineTransform     ---->  CGAffineTransform;

    l.transform           ---->  CATransform3D

 

- (void)affineTransform
{
    CALayer *l = [CALayer layer];
    l.bounds = CGRectMake(0, 0, 100, 100);
    l.backgroundColor = [UIColor lightGrayColor].CGColor;
    //位置
    l.position = CGPointMake(100, 100);
    
    l.contents = (id)[UIImage imageNamed:@"c75c10385343fbf2c6e17e6eb27eca8064388faa"].CGImage;
    [self.view.layer addSublayer:l];
    
#if 0 
    // ------ 仿射变换 ------
    //旋转45度
    l.affineTransform = CGAffineTransformMakeRotation(M_PI/6);
    //比例变换
    CGAffineTransformMakeScale(<#CGFloat sx#>, <#CGFloat sy#>);
    //偏移
    CGAffineTransformMakeTranslation(<#CGFloat tx#>, <#CGFloat ty#>)
#endif
    
#if 0
    // ------ 3D变换 ------
    //旋转
    //注意:旋转90读时图片与人视线平行 --> 看不见图片
    l.transform = CATransform3DMakeRotation(M_PI/4, 1, 1, 1);
    //比例
    CATransform3DMakeScale(<#CGFloat sx#>, <#CGFloat sy#>, <#CGFloat sz#>);
    //偏移
    CATransform3DMakeTranslation(<#CGFloat tx#>, <#CGFloat ty#>, <#CGFloat tz#>)
    //m34 = -1/xxxx
    //CATransform3DMakeRotation 类中 m34为人的视角,有兴趣可以研究一下
#endif
    
}

 

 

 

11.CAShapeLayer和UIBezierPath(贝塞尔曲线)

 

CAShapeLayer

CAShapeLayer是CALayer的子类,是Quare 2D中对图层操作最基本的一个扩展。通过它,我们可以绘制各种图形,特别是不规则图形。

每个CAShapeLayer对象都代表着将要被渲染到屏幕上的形状(shape)。具体的形状由其path(类型为CGPathRef)属性指定,形状可以是任意的,比如星形、菱形等等。

普通的CALayer在初始化时需要指定frame值,它本身是有形状,而且是矩形。CAShapeLayer初始化时也需要指定frame值,但它本身没有形状,它的形状来源于其属性path

 

UIBezierPath

UIBezierPath对象是CGPathRef数据类型的封装。path如果是基于矢量形状的,都用直线和曲线段去创建。我们使用直线段去创建矩形和多边形,使用曲线段去创建弧(arc),圆或者其他复杂的曲线形状。每一段都包括一个或者多个点,绘图命令定义如何去诠释这些点。每一个直线段或者曲线段的结束的地方是下一个的开始的地方。每一个连接的直线或者曲线段的集合成为subpath。一个UIBezierPath对象定义一个完整的路径包括一个或者多个subpaths。

 

12.环形进度条实现

 

13.圆形头像视图

 

posted on 2016-03-13 19:41  Wilson_CYS  阅读(328)  评论(0编辑  收藏  举报

导航