美文网首页
《iOS Core Animation Advanced Tec

《iOS Core Animation Advanced Tec

作者: ShannonChenCHN | 来源:发表于2016-12-02 23:58 被阅读39次

    3. Layer Geometry

    Let no one unversed in geometry enter here.
    ——Sign above the entrance to Plato's Academy

    • UIView 有三个基本的布局属性:frame,bounds 和 center。CALayer 也有 frame,bounds 和 position 三个对应的属性。frame 代表 layer 的外部坐标,bounds 代表内部坐标({0,0}通常相当于layer 的左上角,个别情况除外),center 和 position 一样,代表 anchorPoint 相对 superlayer 的位置。

    • view 的 frame,bounds 和 center 实际上就是对其隐藏在背后的 layer 的对应属性的封装。当你在控制 view 的 frame 的时候,实际上你是在改变 layer 的 frame。

    UIView and CALayer coordinate systems (with example values).png
    • 值得注意的是,当一个 layer 被旋转或者缩放时,它的 frame 变成了 transformed layer 所占据的一片轴向对齐的矩形区域,这也就意味着 frame 的 width 和 height 可能跟 bounds 不匹配了。
    The effect that rotating a view or layer has on its frame property.png
    • anchorPoint 属性决定着 layer 的 frame 相对于其 position的位置。你可以把 anchorPoint 当做是移动 layer 的手柄。默认情况下,anchorPoint 位于 layer 的中心(也就是与中心重合),因此 layer 也是以该点的位置做为中心摆放的。

    • 在 UIView 中并没有暴露 anchorPoint 属性的接口,这也就是为什么 view 的“中点”属性叫做 center 而不是 position 的原因。

    • 一个 layer 的 anchorPoint 是可以被移动的,当你把它放到 layer 的 frame 左上角时,layer 的内容(content)将会被挪到其 position 的右下方。

    The effect that changing the anchorPoint has on the frame.png
    • 像第二章中介绍的 contentsRect 和 contentsCenter 属性一样,anchorPoint 是以单元坐标(相对坐标)为单位的,也就是说,它的坐标相对于 layer 的尺寸是相对的。在 layer 的左上角时是{0,0},在右下角时是{1,1},默认值是在中心{0.5,0.5}。当 anchorPoint 的值小于 0 或者大于 1 时,anchorPoint 就在 layer 的边界(bounds)外了。

    • 当我们改变 anchorPoint 时,position (中心)属性不会发生改变,但是 frame 会跟着变化。

    • 那么,我们为什么需要改变 anchorPoint 的值呢?我们完全可以通过设置 frame 来达到我们想要的位置,改变 anchorPoint 的值话不会反而引起困惑吗?有个场景可以回答这个问题——当 layer 在变换(旋转、缩放)过程中,是以 position 的位置为中心的,所以这时 anchorPoint 就可以发挥作用了。可以参考一下时钟的 demo。

    The four images that make up the clock face and hands.png Laying out the clock views in Interface Builder.png The clock face, with misaligned hands.png The clock face, with correctly aligned hands.png
    • layers 和 views 一样,也是按层级来放置的,layer 的 position 就是相对于它的 superlayer 的 bounds 的。如果 superlayer 移动了,那么其所有 sublayer 也跟着移动。

    • 可能有时候你想知道一个 layer 的绝对位置或者它相对于某一 layer 的位置而非它直接的 superlayer 的位置。CALayer 提供了一些在不同坐标系中转换坐标的方法:

    - (CGPoint)convertPoint:(CGPoint)point fromLayer:(CALayer *)layer;
    - (CGPoint)convertPoint:(CGPoint)point toLayer:(CALayer *)layer;
    - (CGRect)convertRect:(CGRect)rect fromLayer:(CALayer *)layer;
    - (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;
    
    • 在 iOS 中,一个 layer 的 position 是以其 superlayer 的左上角为基准的;而在 Mac OS 上,一个 layer 的 position 是以其 superlayer 的左下角为基准的。Core Animation 提供了 geometryFlipped 属性来翻转 layer 在 superlayer 中的垂直方向上的位置。
    • UIView 只有二维的空间,CALayer 存在三维的空间。除了前面讨论过的 position 和 anchorPoint 属性之外,CALayer 还有 zPosition 和 anchorPointZ 这两个属性,这两个属性都是浮点数值,用来描述layer 在 z 轴方向上的位置。

    • 除了在变换(transform)时要用到 zPosition 外,你唯一可能用到 zPosition 的实际场景是改变你的 layer 的展示层级顺序。通常 layer 是根据其在 superlayer 的 sublayers 数组中的出现的顺序来绘制的,这种算法被称为“画家算法”(painter's algorithm)。通过增大一个 layer 的 zPosition 的值,你可以将其移到其他 zPosition 值更小的 layer 的前面去。值得注意的是,zPosition 仅仅只能改变 layer 的展示顺序,并不能改变 layer 在其 superlayer 的 sublayers 数组中的顺序。

    • -containsPoint:方法可以用来判断一个点(point)是否在该 layer 的 frame 中。

    • -hitTest:方法接受一个 CGPoint 参数,返回一个 frame 包含了该点(point)的最深层的 sublayer 或者其本身,如果该 layer 和 sublayer 的 frame 都不包含改点,则返回 nil。

    相关文章

      网友评论

          本文标题:《iOS Core Animation Advanced Tec

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