美文网首页
CALayer基础知识一

CALayer基础知识一

作者: 小强简书 | 来源:发表于2018-05-02 17:42 被阅读59次

    一、CALayer和UIView
    CALayer与UIView类似,是一些被层级关系树管理的矩形块,和UIView的最大不同是不能处理用户的交互。
    每一个UIView都有一个CALayer的属性,它的责任是创建并且管理这个图层,以确保当子视图层级关系变化的时候,他们的关联图层也同样对应在层级关系树当中有相同的操作。
    iOS提供CALayer和UIView两个平行的层级关系是为了职责分离。UIView主要是对显示内容的管理而 CALayer 主要侧重显示内容的绘制。
    CALayer可以做而UIView不可以做得事情:
    (1)阴影,圆角,边框
    (2)3D变换
    (3)非矩形范围
    (4)透明遮罩
    (5)多级非线性动画

        CALayer *redLayer = [CALayer layer];
        redLayer.backgroundColor = [UIColor redColor].CGColor;
        redLayer.frame = CGRectMake(0, 0, 50, 50);
        [self.view.layer addSublayer:redLayer];
    

    二、寄宿图和contents属性
    1.寄宿图:即为图层中包含的图,CALayer不仅可以创建带有简单颜色的背景图层,还可以包含一张图片。

    2.contents属性
    CALayer可以通过一个contents属性添加图片

       UIImage *image = [UIImage imageNamed:@"icon_logo"];
        
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(50, 50, 50, 100);
        [self.view.layer addSublayer:layer];
        
        layer.contents = (__bridge id)image.CGImage;
    

    需要注意:core foundation 和 cocoa对象不是类型兼容的,需要通过bridged 关键字进行转换。在ARC环境下只需要layer.contents = (id)image.CGImage;id转换就可以了

    3.contentGravity

        layer.contentsGravity = kCAGravityResizeAspect;
    

    类似于UIView中的cotentMode

    4.contentsScale
    contentsScale 属性定义了寄宿图的像素尺寸和视图大小的比例,默认为1.0

        layer.contentsScale = [UIScreen mainScreen].scale;
    

    5.maskToBounds
    maskToBounds对于超出边界的内存剪裁,和UIView的clipsToBounds一样

    6.contentsRect
    contentsRect 是使用了单位坐标,单位坐标指定在0到1中间,是一个相对值,默认的contentsRect是 {0,0,1,1},意味着整个寄宿图都是可见的,如果我们指定为{0,0,0.5,0.5}就只能显示左上角的四分之一的图片。
    这样我们可以得到一个实用的功能,图片拼合的用法——将多张图片整合到一张大图上面,一次性载入,相比多次载入不同的图片,好处是:内存使用,载入时间,渲染性能等等。

    //contentsRect 属性
    - (void)createCALayerContentsRect {
        CALayer *layer1 = [CALayer layer];
        layer1.frame = CGRectMake(200, 100, 50, 50);
        [self.view.layer addSublayer:layer1];
        
        CALayer *layer2 = [CALayer layer];
        layer2.frame = CGRectMake(300, 100, 50, 50);
        [self.view.layer addSublayer:layer2];
        
        [self addSpriteImage:[UIImage imageNamed:@"icon_logo"] withContentRet:CGRectMake(0, 0, 0.5, 0.5) layer:layer1];
        [self addSpriteImage:[UIImage imageNamed:@"icon_logo"] withContentRet:CGRectMake(0.5, 0.5, 0.5, 0.5) layer:layer2];
    }
    
    - (void)addSpriteImage:(UIImage *)image withContentRet:(CGRect)rect layer:(CALayer *)layer {
        layer.contents = (id)image.CGImage;
        layer.contentsGravity = kCAGravityResizeAspect;
        layer.contentsRect = rect;
    }
    

    7.contentsCenter

    contentsCenter 与UIImage里的 - resizableImageWithCapInsets:方法类似。

    三、图层几何学
    1.布局
    UIView有三个布局属性:frame,bounds,center,CALayer对应的叫:frame,bounds,position
    Frame代表图层的外部坐标,bounds是内部坐标{0,0}是图层的左上角。position相当于anchorPoint。
    当操纵视图的frame,实际上改变的是位于视图下方的CALayer的frame,对于视图或者是图层来说,frame是根据bounds,position,transform计算而来的,当对图层做变换的时候,比如旋转或者缩放,frame实际上代表了覆盖在图层旋转之后的整个轴对齐的矩形区域,frame的宽高和bounds可能不一样了。


    1420016966634141.jpeg

    2.锚点
    默认来说,anchorpoint位于图层的中心点,但是anchorpoint可以被移动。

    self.anchorPoint = CGPointMake(0.5f,0.9f);
    

    3.坐标系

    - (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
    - (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;
    
    - (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
    - (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
    
    

    4.翻转的几何结构
    geometryFlipped 设置为yes,则子图层或者子视图本来相对于左上角放置 改为 相对于左下角放置;

    5.Z坐标轴
    CALayer存在一个三维空间当中,除了position和anchorPoint之外,还有zPosition和anchorPointZ。
    可以改变图层的显示绘图顺序

    6.Hit Testing

    CGRectContainsRect(<#CGRect rect1#>, <#CGRect rect2#>)表示rect1和rect2是否相交
    CGRectContainsPoint(<#CGRect rect#>, <#CGPoint point#>)表示rect中是否包含point坐标
    CGRectIntersectsRect(<#CGRect rect1#>, <#CGRect rect2#>)表示rect1中是否包含rect2
    

    -hitTest:方法接受一个CGPoint类型的参数,返回图层本身,用于判断point点击了那个图层

       CGPoint point = [[touches anyObject] locationInView:self.view];
        CALayer *layer = [self.view.layer hitTest:point];
        NSLog(@"%@",layer);
        if (layer == self.redLayer) {
            NSLog(@"yes");
        }
    
    

    相关文章

      网友评论

          本文标题:CALayer基础知识一

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