zoukankan      html  css  js  c++  java
  • Core Animation 文档翻译 (第五篇)—构建Layer的层次结构

    前言


    在APP中大多数情况下,将Layer和View对象结合使用是Layer最好的使用方式。然而,很多时候我们可能需要通过添加单独的Layer对象,以便增加视图继承层次;当为了提高性能,或为了实现View很难实现的特性,此时应该使用Layers,此时也需要知道如何管理我们创建Layer层次。

    将Layers安插进Layer层次结构里


    Layer层次结构在许多方面都和Views层次结构相似。我们将一个Layer嵌入到另外一个Layer里面,此时便在被用作嵌入的Layer(被称为sublayer)和父图层(superlayer)之间形成了父子关系;这种父子关系会对
    sublayer的许多方面产生影响。例如,它的content处于它superlayer的上面,它的position也会相对于它的superlayer的坐标系统,它也会受到被应用到它的superlayer的transforms的影响。


    添加、插入以及移除sublayers


    每一个Layer对象都有用于添加、插入、移除子layer的方法。表4-1概括了这些方法和他们的功能。

    Table 4-1 Methods for modifying the layer hierarchy

    功能 方法 描述
    添加子layer addsubLayer: 为当前的layer添加一个新的sublayer对象,这个要被添加的sublayer会被添加到当前layer的sublayers数组的末尾。相对于sublayers数组中拥有相同zPosition属性值的layer,这个新的sublayer将会呈现在他们的顶部。
    插入layer insertSublayer:above: insertSublayer:atIndex: insertSublayer:below: 以相对于另外的sublayer的position或者index将sublayer插入sublayer层结构。当要插入到另外的sublayer前面或者后面时候,我们只需要指定sublayer在数组中的位置。Layers对象是否可显示在屏幕上,第一取决于他们的zPosition属性,第二取决于他们在sublayer数组。
    移除layers removeFromSuperlayer 从父layer中移除指定的sublayer
    交换layers的位置 replaceSublayer:with: 将两个sublayer的位置进行交换。如果我们要插入sublayer已经存在于其他的layer层次结构中了,那么这个sublayer将会先从之前的层次中移除

    对于我们自己创建的Layer对象,可以使用上面的方法;我们不可以使用这些方法调整Layer-backed View 的Layer。但是一个Layer-backed View能够为我们单独创建的Layers当做父图层。


    为Sublayers设置位置和尺寸


    当添加和插入sublayer的时候,在sublayer显示到屏幕上之前,我们必须为sublayer设置size和position。我们也可以在将sublayer添加到图层上之后再修改size和position,但是我们最好将在创建Layer的时候就设置这两个值作为习惯。

    使用bounds属性可以设置sublayer的尺寸,使用position属性可以
    设置sublayer在它的superlayer内的位置。它的bounds的原点一直是(0,0),尺寸size就是我们设置的大小(以point为单位)。position属性适合layer的anchor point相关联的,anchor point默认是在layer的中心。如果我们不设置这些值,核心动画将会设置出事宽高为0,并设置position为(0,0)。

    myLayer.bounds = CGRectMake(0, 0, 100, 100);
    myLayer.position = CGPointMake(200, 200);
    

    重要提示:确保layer的宽高为整数值。(一般我们使用的值都是以point位单位的而不是pixel,所以至少要保证在当前设备上的为分辨率的整数个数。)


    Layer的层次是如何影响动画的


    子layer的动画行为会受到superlayer的一些属性的影响。speed属性就是其中之一,他将会和动画的speed相乘,这个属性值默认被设置为1.0,若改为2.0将会引起动画以原来速度的2倍运行并以原来一半的时间结束,这个属性不仅仅影响它自身还影响它的sublayers。这个改变是可以逐层相乘的累积的。如果sublayer和super都被设置为2.0的speed,sublayer的动画将会以原速度的4倍运行。
    许多layer的调整都会对他包含的sublayers产生相应的影响。例如,对layer使用旋转transform,则它所有的sublayer也会受到影响。相似的,改变一个layer的opacity属性也将会影响它的sublayers。layer尺寸的改变遵循布局规则(Adjusting the Layout of Your Layer Hierarchies.


    调整Layer层次的布局


    为了响应superlayer的调整,核心动画为调整sublayer的size和position提供几个配置项。在iOS中layer-backed view的广泛使用是的layer层次的创建显得没那么重要;仅仅支持手动更新layout。对于OSX而言,有几个可用的配置能够使我们方便的管理layer层次。

    Layer的层次layout仅当我们使用单独创建的Layer对象时才有意义。如果APP中所有的layer都是和view对应关联的,可以使用基于view的layout实现view响应的变化更新size和position。

    Sublayers和剪裁


    不像Views,一个superLayer不会自动裁剪超过它的bounds矩形区域的sublayers的content。superlayer允许它的sublayers默认完全不显示。然而,通过将属性maksToBunnds的值设为YES,可以启用裁剪操作。

    Layer的圆角也被Layer的裁剪遮罩的形状包含在内。图4-3显示了masksToBounds属性是如何影响带有圆角的layer的。当masksToBounds属性被置为NO的时候,即使sublayer超出了superlayer的bounds,sublayer也会完整的展示。将masksToBounds属性改为YES将会引起他们sublayer的裁剪。

    图4-3 根据superlayer的bounds裁剪sublayer

    在两个Layers中进行坐标转换


    有时,我们需要将一个Layer内的某个点坐标值转化为屏幕内其他layer内的坐标值。CALayer类提供了几个简单的转换方法:

    除了转换点和矩形值之外,通过使用convertTime:fromLayer:convertTime:toLayer: ,我们还能在layers之间转换time值。每一个layer都有他们自己的time空间,并使用它的time空间来和系统参考系同步动画的开始和结束。这些time空间默认是同步的;但是,如果我们改变一些layer的speed,那么那些layer的time空间也将会相应的变化。我们可以使用时间转换方法获取这些因子,并确保两个layer的时间函数是同步的。

  • 相关阅读:
    再谈TextField
    IOS-TextField知多少
    leftBarButtonItems
    LeftBarButtonItems,定制导航栏返回按钮
    Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法 Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法
    Unrecognized Selector Sent to Instance问题之诱敌深入关门打狗解决办法
    UNRECOGNIZED SELECTOR SENT TO INSTANCE 问题快速定位的方法
    Present ViewController,模态详解
    UILABEL AUTOLAYOUT自动换行 版本区别
    iOS自动布局解决警告Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
  • 原文地址:https://www.cnblogs.com/zhouyubo/p/8419873.html
Copyright © 2011-2022 走看看