zoukankan      html  css  js  c++  java
  • iOS CALayer总结——图层几何

    最近看了一下关于图层和动画的内容,所以写了一份总结,算是对这些内容的汇总吧,都是一些简单的基础知识,不知道大家都了不了解。
    除了和用户的交互之外,图层的很多属性和视图基本上都是一样的,今天就先从CALayer的一些基础的属性入手,没有套路和技巧,只是对属性的介绍:

    一、contents

    contents是CALayer的一个属性:@property(nullable, strong) id contents;它的类型是id,使用contents我们可以为一个普通的图层添加一张图片,但是在赋值的时候,只有CGImageRef类型才有效,并且需要使用bridged关键字进行转换,因为CGImageRef并不是一个Cocoa对象,而是一个Core Foundation类型,所有正确的赋值方式为:

    UIImage *image = [UIImage imageNamed:@"image_1.jpg"];
        self.layerView.layer.contents = (__bridge id)image.CGImage;
    

    效果和使用UIImageView时一样一样的:


    效果图.png

    和contents相关的还有以下几个属性:
    contentsGravity、contentsScale、contentsRect、contentsCenter

    contentsGravity

    contentsGravity和UIView的contentMode属性的作用是相似的,我们可以看到上面的效果图中的图片被拉伸了,我们平时在使用UIImageView展示图片的时候也会出现这种情况,我们设置contentMode属性就可以解决,在图层中,我们使用contentsGravity属性就可以了。
    contentsGravity有以下这些可选的值:

    kCAGravityCenter
    kCAGravityTop
    kCAGravityBottom
    kCAGravityLeft
    kCAGravityRight
    kCAGravityTopLeft
    kCAGravityTopRight
    kCAGravityBottomLeft
    kCAGravityBottomRight
    kCAGravityResize
    kCAGravityResizeAspect
    kCAGravityResizeAspectFill
    值得注意的是:这些值并不是枚举,他们都是常量字符串。
    为我们上面的代码再添加一句:

    self.layerView.layer.contentsGravity = kCAGravityResizeAspect;
    

    我们可以发现,图片就正常了,效果如下:

    contentsScale

    contentsScale 属性定义了contents中图片的的像素尺寸和视图大小的比例,它用来判断在绘制图层的时候应该为contents创建的空间大小,和需要显示的图片的拉伸度。如果contentsScale设置为1.0,将会以每个点1个像素绘制图片,如果设置为2.0,则会以每个点2个像素绘制图片,这就是Retina屏幕了。
    如果我们已经使用contentsGravity属性使图片拉伸了,那么我们再设置contentsScale就会失效(不是所有的contentsGravity的值都会拉伸图片)。
    我们先将设置contentsGravity的代码改为:
    self.layerView.layer.contentsGravity = kCAGravityCenter;
    然后添加:

    self.layerView.layer.contentsScale = image.scale;
    我们发现显示的图片跟图片本身大小一致:

    效果图-3.png

    我这里使用的是1倍图,如果我们为图片的名字后面添加一个@2x,然后就变成这样了:


    效果图-4.png

    原因就不用我多说了吧。

    contentsRect

    contentsRect属性规定了我们在contents中可以显示的图片的区域,这个理解起来也很容易,但是要注意的是:contentsRect不是一个绝对值(点或者像素),而是一个相对值,以左上角为坐标原点,单位坐标在0~1之间,当然也可以是负数。设置了contentsRect属性只显示左上角1/4区域:

    self.layerView.layer.contentsRect = CGRectMake(0, 0, 0.5, 0.5);
    

    效果图如下:


    效果图-5.png
    contentsCenter

    我们在日常的开发中,有时候UI给的图片我们在显示的时候需要对图片进行拉伸,但是又想只拉伸中间的部分,四周的一些区域不拉伸,我们会使用-resizableImageWithCapInsets:方法设置一下四周不被拉伸的区域,contentsCenter属性在图层中起到的也是这个作用,contentsCenter的默认值是{0, 0, 1, 1},也就是整张图片都被拉伸,如果将值改为{0.25,0.25,0.5,0.5}就表示x,y都从左上角1/4处开始,宽和高分别为图片尺寸的一半大小,所围成的区域被拉伸,其他区域不拉伸。由于我找的图片素材效果不太明显,所有就不贴效果图了。

    二、几何属性

    在图层的几个几何属性中,我们重点介绍anchorPoint
    不过在此之前也简单说一下frameboundsposition,一句话总结:frame代表了图层的外部坐标(相对于父图层),bounds是内部坐标(相对于自身),position代表了相对于父图层anchorPoint所在的位置。改变图层的boundsboundstransform,都会令frame发生改变。
    比如,我们将图层旋转45度,然后看一下旋转前后图层的frame:

    NSLog(@"x:%f,y:%f",self.layerView.layer.frame.origin.x,self.layerView.layer.frame.origin.y);
        self.layerView.layer.affineTransform = CGAffineTransformMakeRotation(M_PI_4);
    NSLog(@"x:%f,y:%f",self.layerView.layer.frame.origin.x,self.layerView.layer.frame.origin.y);
    

    x:112.500000,y:233.500000
    x:63.756313,y:209.756313

    anchorPoint

    上面说到,position代表了相对于父图层anchorPoint所在的位置,通过改变anchorPoint,图层的frame也会发生改变。要理解anchorPoint很容易,直接上代码就很直观了:

    创建两个位置和大小都相同的layer,layer1为参照图层,此时两个图层是重合的,

    CALayer *layer1 = [[CALayer alloc]init];
        layer1.frame = CGRectMake(100, 200, 150, 100);
        layer1.backgroundColor = [UIColor redColor].CGColor;
        [self.view.layer addSublayer:layer1];
        CALayer *layer2 = [[CALayer alloc]init];
        layer2.frame = CGRectMake(100, 200, 150, 100);
        layer2.backgroundColor = [UIColor greenColor].CGColor;
        [self.view.layer addSublayer:layer2];
        NSLog(@"frame:{%.0f,%.0f,%.0f,%.0f}",layer2.frame.origin.x,layer2.frame.origin.y,layer2.frame.size.width,layer2.frame.size.height);
        NSLog(@"bounds:{%.0f,%.0f,%.0f,%.0f}",layer2.bounds.origin.x,layer2.bounds.origin.y,layer2.bounds.size.width,layer2.bounds.size.height);
        NSLog(@"positon:{%.0f,%.0f}",layer2.position.x,layer2.position.y);
        NSLog(@"anchorPoint:{%.0f,%.0f}",layer2.anchorPoint.x,layer2.anchorPoint.y);
    
     
    anchorPoint改变前.png

    改变layer2的anchorPoint为{0,0}:

    layer2.anchorPoint = CGPointMake(0, 0);
    
    anchorPoint改变后.png

    anchorPoint是在做图层变换和动画的时候,非常重要的一个属性,它是图层变换的一个把柄,比如图层在做旋转的时候,就是以anchorPoint为基点旋转的。实际上,在UIView中也有anchorPoint,只不过,系统并没有暴露这个属性,UIView的center属性和图层的position属性是同一个概念,anchorPoint默认是{0.5,0.5},所以UIView得center就是中心点了。

    zPosition

    CALayer存在于一个三维空间当中,它还有一个用来表示图层在Z轴方向上位置的属性zPosition,默认为0,如果改变这个属性,就会改变多个图层之间的显示顺序。就用上面的例子演示一下,改变红色图层的zPosition,图层是一个非常非常薄的东西,所以我们只需要为zPosition设置一个比较小的值就可以了,比如说:1.0:

     layer1.zPosition = 1.0f;
    
    效果图.png

    这样,两个图层的顺序就发生了改变,不过需要注意的是:这只是用户视角上看起来两个图层的顺序改变了,实际上两个图层在父图层上还是原来的顺序。

    关于设置图层效果的属性,相信大家其实再熟悉不过了:
    比如:圆角(conrnerRadius)、边框(borderWidthborderColor)、阴影(shadowColorshadowOffsetshadowRadiusshadowOpacity)、
    图层蒙版(mask),在这里,就不啰嗦了,还需要节省时间,在接下来的文章中去总结更多更丰富的关于图层的内容。

  • 相关阅读:
    C# .NET Socket封装
    Web页面实现后台数据处理进度与剩余时间的显示
    彻底解决“从客户端中检测到有潜在危险的Request.Form值”
    自己封装的Windows7 64位旗舰版,微软官网上下载的Windows7原版镜像制作,绝对纯净版
    Oracle导入导出命令
    Oracle创建用户、表空间并设置权限
    Web Service 和WCF的比较
    Win10下IIS配置图解、MVC项目发布图解、IIS添加网站图解
    图表控件MsChart使用demo
    Excel中的宏--VBA的简单例子
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/11274138.html
Copyright © 2011-2022 走看看