iOS核心动画技巧学习 -- CALayer常用属性

  • contents属性
    • 类型
      • id类型的历史原因:因为在MAC OS系统上,这个属性对CGImageNSImage的类型值都起作用
      • 但是在iOS平台将UIImage赋值给它,编译会通过,然后你得到的图层将是空白的
      • 但是其实我们真正要赋值的类型应该是CGImageRef,是一个指向CGImage结构的指针;不过UIImage有一个CGimage属性,它返回一个CGImageRef,点击进去UIImage的头文件可以看到:@property(nullable, nonatomic,readonly) CGImageRef CGImage; // returns underlying CGImageRef or nil if CIImage based
    • 使用
      • 直接使用属性会报错,因为CGImageRef并不是一个真正的Cocoa对象,而是一个Core Foundation类型
      • __bridge转换
  • contentGravity属性
    • 问题: 上面我们使用CALayer在一个普通的UIView上显示了一张图片,但是我们发现了,图片中的霉霉变胖了(虽然现实中也变胖了不少,- -!),因为加载的图片不是一个方的为了适应视图,图片被拉伸了
    • UIImageView: view.contentMode = UIViewContentModeScaleAspectFit;
    • CALayer: 与contentMode对应的属性是contentGravity,是一个NSString类型,而不是想contentMode是个枚举类型,此处我们使用self.layerView.layer.contentsGravity = kCAGravityResizeAspect;后,看霉霉减肥成功啦, : )
    • 具体值
      • kCAGravityCenter
      • kCAGravityTop
      • kCAGravityBottom
      • kCAGravityLeft
      • kCAGravityRight
      • kCAGravityTopLeft
      • kCAGravityTopRight
      • kCAGravityBottomLeft
      • kCAGravityBottomRight
      • kCAGravityResize
      • kCAGravityResizeAspect
      • kCAGravityResizeAspectFill
  • contentsScale属性
    • 默认值 : 1.0
    • 此处由于设置了 contentsGravity属性,图片已经被拉伸以适应图层的边界,所以设置contentsScale没有作用
    • 如果单纯的想放大图层的contents图片,可以通过使用图层的transform``affineTransform来达到目的
    • contentsScale其实属于支持高分辨率屏幕机制的一部分.用来判断再绘制图层的时候应该为图片创建的空间大小和显示的图片的拉伸度(假设没有手动设置contentsGravity),的UIView有个类似的功能但是用到非常少的contentScaleFactor属性
    • contentsScale设置为1.0,将会以每个点1个像素绘制图片,如果2.0,将会以每个点2个像素绘制图片(就是Retina屏幕),但是设置contentsScale并不会影响我们使用kCAGravityResizeAspect,因为kCAGravityResizeAspect就是拉伸图片以适应图层,不会考虑分辨率的问题,但是设置contentsGravity为不会拉伸图片的kCAGravityCenter,就会有区别,如图
    • 原因:因为CGImage没有像UIImage的拉伸概念,当我们使用UIImage类去读取我们的图片时候,他读取了高质量Retina版本的图片,然后用CGImage来设置图层的内容时,拉伸这个因素在转换的时候就丢失了
    • 解决:手动设置 contentsScale
  • masksToBounds属性
    • UIViewclipsToBounds属性来决定是否显示超出边界的内容
    • CALayermasksToBounds与之对应
  • contentsRect属性
    • CALayercontentsRect属性允许我们在图层边框里面显示图片的一个区域,它与bounds``frame不同,contentsRect不是按 来计算而是用了单位坐标 ,是一个0到1之间的相对值,是相对于图层里面的图片的尺寸的
      • 点 —– 逻辑像素,硬件设备上最小的显示单元;标准设备上一个点就是一个像素,5s,6,7,8都是一个点2x2个像素,6p,7p,8p就是3x3个
      • 像素 —– 像素是组成图象的最基本单元要素,一个像素有多大主要取决于显示器的分辨率,相同面积不同分辨率的显示屏,其像素点大小就不相同
      • 单位 —– 对于与图片大小或是图层边界相关的显示,单位坐标是一个方便的度量方式, 当大小改变的时候,也不需要再次调整。单位坐标在OpenGL这种纹理坐标系统中用得很多,Core Animation中也用到了单位坐标
    • 默认值是 {0,0,1,1},默认整个图片是可见的
    • 用处 : 将多张图片打包整合到一张图片一次性载入,相比多次载入不同的图片,会节省内存 载入时间,渲染性能等方面,但是用的要求比较苛刻,不再讨论
  • contentsCenter属性
    • 如其意,它跟图片的位置没有关系,它定义了一个固定的边框和一个在图层上可拉伸的区域
    • Interface Builder窗口也有,感兴趣可以自己去改变值看看效果
这个人很帅<br>他什么都不想说<br>