美文网首页
CALayer-拾遗

CALayer-拾遗

作者: lmfei | 来源:发表于2020-04-13 22:59 被阅读0次

CALayer是什么?

在iOS中,UIView是我们构建UI的基础单元,而UIView之所以可以显示各种元素靠的就是CALayer。
当创建UIView对象时,UIView内部会自动创建一个层,通过UIView的layer可以获取这个主layer,当UIView需要显示内容到屏幕上时,会执行一系列绘制方法将所有内容绘制在自己的层上,绘制完毕后,系统会将层拷贝到屏幕上,这样就完成了UIView的显示。

CALayer和UIView如何选择?

CALayer和UIView都可以显示内容,那他们有什么区别?
通过类的定义可以知道CALayer是继承自CALayer的,而UIView是继承自UIResponder,从这我们就了解了CALayer不能响应事件,而需要响应事件的时候,我们就需要使用UIView,如果不需要响应事件时,两者都可以,但是CALayer的性能会比UIView好很多。

CALayer的常见属性

  • bounds - 设置CALayer的宽度和高度
  • backgroundColor - 设置CALayer的背景色
  • position - 设置CALayer的中心点
  • anchorPoint - 设置锚点,初始值为(0.5, 0.5),它是表示位于宽高的比例,初始位置与position重合
    前面几个属性很好理解,下面详细记录下anchorPoint

anchorPoint

重新设置anchorPoint,相当于anchorPoint的坐标不动,然后移动frame
如果设置0,0,则需要往右下角的点移动view,直到比例满足0,0的位置
如果设置0,1,则需要往右上角移动view,直到比例满足0,1的位置
如果设置为1,0,则需要向左下角移动view,直到比例满足1,0的位置
如果设置为1,1,则需要向左上角移动view,,直到比例满足1,1的位置

layer如何为图片设置圆角与阴影

我们知道,在UIImageView显示图片的时候,只是设置cornerRadius,是无法实现的,必须要加上maskToBounds=YES,这是为什么?
当绘制一张图片到图层上的时候会重新创建一个图层添加到当前图层,这样设置圆角后,只是底图层有圆角效果,而子图层并没有圆角效果,所以圆角效果是显示不出来的,这时只有设置masksToBounds为YES时,才能让子图层按底图层裁剪子图层!

那我设置了圆角效果后,再加上阴影效果,这种情况会怎么样呢?
不难想,阴影效果肯定会失效,masksToBounds会将子视图裁剪掉,而阴影效果恰巧是作为外边框绘制的,这样就会被裁剪掉
如果我们希望图层展示图片既有圆角又有阴影,要怎么解决呢
可以通过曲线救国,借助两个图层来做,容器图层添加阴影效果
图片图层做图片裁剪

下面再看下在layer层同时设置图片与阴影的方法

在看这个问题前,我们先来看下layer如何设置图片,以及出现图片倒立的问题如何解决
  1. 通过contents赋值设置图片
- (void)drawCornerAndShadow {   
    CALayer *photoLayer = [CALayer new];
    photoLayer.bounds = bounds;
    photoLayer.position = position;
    photoLayer.backgroundColor = [UIColor redColor].CGColor;
    photoLayer.cornerRadius = cornerRadius;
    photoLayer.masksToBounds = YES;
    photoLayer.borderColor = [UIColor whiteColor].CGColor;
    photoLayer.borderWidth = borderW;
    UIImage *image=[UIImage imageNamed:@"photo.png"];
    [photoLayer setContents:(id)image.CGImage];
    [self.view.layer addSublayer:photoLayer];
}

通过这种设置不会产生倒立的问题

  1. 通过layer的delegate进行绘制
- (void)drawCornerAndShadow {
    CALayer *photoLayer = [CALayer new];
    photoLayer.bounds = bounds;
    photoLayer.position = position;
    photoLayer.backgroundColor = [UIColor redColor].CGColor;
    photoLayer.cornerRadius = cornerRadius;
    photoLayer.masksToBounds = YES;
    photoLayer.borderColor = [UIColor whiteColor].CGColor;
    photoLayer.borderWidth = borderW;
   
    //设置CALayerDelegate
    photoLayer.delegate = self;
    [self.view.layer addSublayer:photoLayer];
    //调用图层setNeedDisplay,否则代理不会执行
    [photoLayer setNeedsDisplay];
}

-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{          
    CGContextSaveGState(ctx);
    UIImage *image=[UIImage imageNamed:@"photo.png"];
    //注意这个位置是相对于图层而言的不是屏幕
    CGContextDrawImage(ctx, CGRectMake(0, 0, Photo_W, Photo_W), image.CGImage);
}

这种显示图片的方法,有几个关键步骤需要做:

  • 设置CALayerDelegate代理为当前VC
  • 实现代理并在代理中设置图片
  • 执行layer的setNeedsDisplay,否则代理不会执行

这种情况虽然图片显示出来了,但是图片确是倒立的
如何解决倒立的问题呢

首先,我们要了解为什么图片会倒立?
因为UIKit的坐标系,与CoreGraphics中坐标系不同,UIKit是x轴向右为正向,y轴向下为正向;而CoreGraphics是x轴向右为正向,y轴向上为正向。
所以解决这个问题,只需要让图片以x轴旋转180度即可

  • 方案一 drawLayer新增选择方法
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{    CGContextSaveGState(ctx);
    //解决图片倒立的问题-方法1
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -Photo_W);
    
    UIImage *image=[UIImage imageNamed:@"photo.png"];
    //注意这个位置是相对于图层而言的不是屏幕
    CGContextDrawImage(ctx, CGRectMake(0, 0, Photo_W, Photo_W), image.CGImage);
}
  • 方案二 设置transform
photoLayer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
  • 方案三 通过keyPath设置tansform
[photoLayer setValue:@M_PI forKeyPath:@"transform.rotation.x"];

接下来我们来看下如果通过两个layer完成圆角与阴影的设置

- (void)drawCornerAndShadow {
    CGPoint position = CGPointMake(160, 200);
    CGRect bounds = CGRectMake(0, 0, Photo_W, Photo_W);
    CGFloat cornerRadius = Photo_W/2;
    CGFloat borderW = 2;
    CALayer *layerShadow = [CALayer new];
    layerShadow.bounds = bounds;
    layerShadow.position = position;
    layerShadow.cornerRadius = cornerRadius;
    layerShadow.shadowColor = [UIColor orangeColor].CGColor;
    layerShadow.shadowOffset = CGSizeMake(2, 1);
    layerShadow.shadowOpacity = 1;
    layerShadow.borderColor = [UIColor yellowColor].CGColor;
    layerShadow.borderWidth = borderW;
    [self.view.layer addSublayer:layerShadow];
    
    CALayer *photoLayer = [CALayer new];
    photoLayer.bounds = bounds;
    photoLayer.position = position;
    photoLayer.backgroundColor = [UIColor redColor].CGColor;
    photoLayer.cornerRadius = cornerRadius;
    photoLayer.masksToBounds = YES;
    photoLayer.borderColor = [UIColor whiteColor].CGColor;
    photoLayer.borderWidth = borderW;
    UIImage *image=[UIImage imageNamed:@"photo.png"];
    [photoLayer setContents:(id)image.CGImage];
    [self.view.layer addSublayer:photoLayer];
}

简简单单,完成设置

生活如此美好,今天就点到为止。。。

相关文章

网友评论

      本文标题:CALayer-拾遗

      本文链接:https://www.haomeiwen.com/subject/fmpomhtx.html