CALayer总结(一)

1.geometryFlipped   设置为yes,则子图层或者子视图本来相对于左上角放置 改为 相对于左下角放置;

2.contents

3.contentGravity:

kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
kCAGravityResize
kCAGravityResizeAspect
kCAGravityResizeAspectFill
4.contentsScale

5.maskToBounds

6.contentsRect

7.contentsCenter

8.自己绘制寄宿图

方法-:继承UIView并实现-drawRect:(如果你不需要寄宿图,那就不要创建这个方法了,这会造成CPU资源和内存的浪费,这也是为什么苹果建议:如果没有自定义绘制的任务就不要在子类中写一个空的-drawRect:方法。)

方法二:CALayer有一个可选的delegate属性,参考代码如下:

blueLayer.delegate = self;

[blueLayer display];
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
  //draw a thick red circle
  CGContextSetLineWidth(ctx, 10.0f); 
  CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
  CGContextStrokeEllipseInRect(ctx, layer.bounds);
}
  • 我们在blueLayer上显式地调用了-display。不同于UIView,当图层显示在屏幕上时,CALayer不会自动重绘它的内容。它把重绘的决定权交给了开发者。

  • 尽管我们没有用masksToBounds属性,绘制的那个圆仍然沿边界被裁剪了。这是因为当你使用CALayerDelegate绘制寄宿图的时候,并没有对超出边界外的内容提供绘制支持。

9.布局:

frame并不是一个非常清晰的属性,它其实是一个虚拟属性,是根据bounds,position和transform计算而来,所以当其中任何一个值发生改变,frame都会变化。相反,改变frame的值同样会影响到他们当中的值;

3.2.jpeg

锚点

3.3.jpeg

10.坐标系

- (CGPoint)convertPoint:(CGPoint)point fromLayer:(CALayer *)layer; 
- (CGPoint)convertPoint:(CGPoint)point toLayer:(CALayer *)layer; 
- (CGRect)convertRect:(CGRect)rect fromLayer:(CALayer *)layer;
- (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;
11.zPosition
增加图层的zPosition,就可以把图层向相机方向前置,于是它就在所有其他图层的前面了(或者至少是小于它的zPosition值的图层的前面);同样适用于视图的layer
12.Hit Testing
CALayer并不关心任何响应链事件,所以不能直接处理触摸事件或者手势。但是它有一系列的方法帮你处理事件:-containsPoint:和-hitTest:。
13.自动布局
如果想随意控制CALayer的布局,就需要手工操作。最简单的方法就是使用CALayerDelegate如下函数:
- (void)layoutSublayersOfLayer:(CALayer *)layer;
当图层的bounds发生改变,或者图层的-setNeedsLayout方法被调用的时候,这个函数将会被执行。这使得你可以手动地重新摆放或者重新调 整子图层的大小,但是不能像UIView的autoresizingMask和constraints属性做到自适应屏幕旋转。
14.conrnerRadius

 默认情况下,这个曲率值只影响背景颜色而不影响背景图片或是子图层。不过,如果把masksToBounds设置成YES的话,图层里面的所有东西都会被截取

15.shadowOpacity

若要改动阴影的表现,你可以使用CALayer的另外三个属性:shadowColor,shadowOffset和shadowRadius

16.shadowPath属性

我们已经知道图层阴影并不总是方的,而是从图层内容的形状继承而来。这看上去不错,但是实时计算阴影也是一个非常消耗资源的,尤其是图层有多个子图层,每个图层还有一个有透明效果的寄宿图的时候。

如果你事先知道你的阴影形状会是什么样子的,你可以通过指定一个shadowPath来提高性能;

17.图层蒙板

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIImageView *imageView;

@end

@implementation ViewController

- (void)viewDidLoad

{

    [super viewDidLoad];

    //create mask layer

    CALayer *maskLayer = [CALayer layer];

    maskLayer.frame = self.imageView.bounds;

    UIImage *maskImage = [UIImage imageNamed:@"1"];

    maskLayer.contents = (__bridge id)maskImage.CGImage;

    //apply mask to image layer?

    self.imageView.layer.mask = maskLayer;

    self.imageView.image=[UIImage imageNamed:@"2"];

}

@end

CALayer蒙板图层真正厉害的地方在于蒙板图不局限于静态图。任何有图层构成的都可以作为mask属性,这意味着你的蒙板可以通过代码甚至是动画实时生成。

18.shouldRasterize

实现组透明的效果,如果它被设置为YES,在应用透明度之前,图层及其子图层都会被整合成一个整体的图片,这样就没有透明度混合的问题了;

为了启用shouldRasterize属性,我们设置了图层的rasterizationScale属性。默认情况下,所有图层拉伸都是1.0, 所以如果你使用了shouldRasterize属性,你就要确保你设置了rasterizationScale属性去匹配屏幕,以防止出现Retina屏幕像素化的问题。

button2.layer.shouldRasterize = YES;
button2.layer.rasterizationScale = [UIScreen mainScreen].scale;

19.变换(CGAffineTransform)

view.transform=CGAffineTransformMakeRotation(M_PI_4) <---->self.view.layer.affineTransform=CGAffineTransformMakeRotation(M_PI_4) ;
CGAffineTransformMakeRotation(CGFloat angle) 
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
混合变换
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)     
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)      
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
参考代码:
    CGAffineTransform transform = CGAffineTransformIdentity; //scale by 50%
    transform = CGAffineTransformScale(transform, 0.5, 0.5); //rotate by 30 degrees
    transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0); //translate by 200 points
    transform = CGAffineTransformTranslate(transform, 200, 0);
    //apply transform to layer
    self.layerView.layer.affineTransform = transform;

设置CGAffineTransform的矩阵值,做任意变换:

    CGAffineTransform transform = CGAffineTransformIdentity;
    transform.c = -x;
    transform.b = y;

20.变换(CATransform3D)

对应layer的transform属性
CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz) 
CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)

5.7.jpeg

 

transform.m34---->应用透视效果

21.sublayerTransform

CALayer有一个属性叫做sublayerTransform。它也是CATransform3D类型,但和对一个图层的变换不同,它影响到所有的子图层。这意味着你可以一次性对包含这些图层的容器做变换,于是所有的子图层都自动继承了这个变换方法。

22.doubleSided

CALayer有一个叫做doubleSided的属性来控制图层的背面是否要被绘制。这是一个BOOL类型,默认为YES,如果设置为NO,那么当图层正面从相机视角消失的时候,它将不会被绘制。

23.CAShapeLayer 

使用CAShapeLayer有以下一些优点:

  • 渲染快速。CAShapeLayer使用了硬件加速,绘制同一图形会比用Core Graphics快很多。

  • 高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。

  • 不会被图层边界剪裁掉。一个CAShapeLayer可以在边界之外绘制。你的图层路径不会像在使用Core Graphics的普通CALayer一样被剪裁掉(如我们在第二章所见)。

  • 不会出现像素化。当你给CAShapeLayer做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。

24.CATextLayer

CATextLayer比UILabel有着更好的性能表现,同时还有额外的布局选项并且在iOS 5上支持富文本。

让我们编辑一下示例使用到NSAttributedString(见清单6.3).iOS 6及以上我们可以用新的NSTextAttributeName实例来设置我们的字符串属性,但是练习的目的是为了演示在iOS 5及以下,所以我们用了Core Text,也就是说你需要把Core Text framework添加到你的项目中。否则,编译器是无法识别属性常量的。

UILabel的替代品

每一个UIView都是寄宿在一个CALayer的示例上。这个图层是由视图自动创建和管理的,那我们可以用别的图层类型替代它么?一旦被创建,我们就无法代替这个图层了。但是如果我们继承了UIView,那我们就可以重写+layerClass方法使得在创建的时候能返回一个不同的图层子类。UIView会在初始化的时候调用+layerClass方法,然后用它的返回类型来创建宿主图层。

把CATextLayer作为宿主图层的另一好处就是视图自动设置了contentsScale属性。

25.CATransformLayer

在立方体示例,我们将通过旋转camara来解决图层平面化问题而不是像立方体示例代码中用的sublayerTransform。这是一个非常不错的技巧,但是只能作用域单个对象上,如果你的场景包含两个立方体,那我们就不能用这个技巧单独旋转他们了。 

CATransformLayer不同于普通的CALayer,因为它不能显示它自己的内容。只有当存在了一个能作用域子图层的变换它才真正存在。CATransformLayer并不平面化它的子图层,所以它能够用于构造一个层级的3D结构

26.CAGradientLayer

CAGradientLayer是用来生成两种或更多颜色平滑渐变的。用Core Graphics复制一个CAGradientLayer并将内容绘制到一个普通图层的寄宿图也是有可能的,但是CAGradientLayer的真正好处在于绘制使用了硬件加速。

27.CAReplicatorLayer

CAReplicatorLayer的目的是为了高效生成许多相似的图层。它会绘制一个或多个图层的子图层,并在每个复制体上应用不同的变换。

instanceCount属性指定了图层需要重复多少次。instanceTransform指定了一个CATransform3D 3D变换(这种情况下,下一图层的位移和旋转将会移动到圆圈的下一个点)。变换是逐步增加的,每个实例都是相对于前一实例布局。这就是为什么这些复制体最终不会出现在同一位置上;

CAReplicatorLayer真正应用到实际程序上的场景比如:一个游戏中导弹的轨迹云,或者粒子爆炸。除此之外,还有一个实际应用是:反射。

28.CAScrollLayer

CAScrollLayer有一个-scrollToPoint:方法,它自动适应bounds的原点以便图层内容出现在滑动的地方。注意,这就是它做的所有事情。前面提到过,Core Animation并不处理用户输入,所以CAScrollLayer并不负责将触摸事件转换为滑动事件,既不渲染滚动条,也不实现任何iOS指定行为例如滑动反弹(当视图滑动超多了它的边界的将会反弹回正确的地方)。

 

posted @ 2016-05-27 18:04  潜意识  阅读(4915)  评论(0编辑  收藏  举报