CALayer什么时候有presentationLayer?

时间:2017-08-16 21:24:43

标签: swift macos calayer appkit presentation-layer

我正在使用CALayers,我希望在动画运行时检索有关图层子图层状态的一些信息。现在我知道我可以通过调用mySublayer.presentation()并访问返回的图层属性来从子图层的表示层中检索信息。

但是返回值是一个可选值,实际上相对经常返回nil。在我的特定情况下,调用发生在我的图层的layoutSublayers()内(图层的超级层我想要的信息)。

这就是为什么我想知道:一个图层何时有一个表示层,什么时候没有一个? 不幸的是,我无法在Apple的文档中找到任何相关内容。

非常感谢!

1 个答案:

答案 0 :(得分:6)

  

图层何时具有表示层

当它是渲染树的一部分时。一个图层始终在屏幕上呈现为其表示层。

您获得nil的原因是您正在查看早期layoutSublayers()内的表示层。这正是图层有一个表示层的时候;我们正在第一次配置渲染树。

这里有一些测试代码可以告诉你发生了什么:

func delay(_ delay:Double, closure:@escaping ()->()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
class MyLayer : CALayer {
    override func layoutSublayers() {
        print("here1")
        if let subs = self.sublayers {
            for lay in subs {
                print(lay.presentation() as Any)
            }
        }
        super.layoutSublayers()
        print("here2")
        if let subs = self.sublayers {
            for lay in subs {
                print(lay.presentation() as Any)
            }
        }
    }
}
class MyView : UIView {
    override class var layerClass: AnyClass { return MyLayer.self }
}
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let lay = CALayer()
        lay.backgroundColor = UIColor.black.cgColor
        lay.frame = CGRect(x: 10, y: 10, width: 10, height: 10)
        self.view.layer.addSublayer(lay)
        print(lay.presentation() as Any)
        delay(1) {
            print(lay.presentation() as Any)
            print("let's try rerendering")
            self.view.setNeedsLayout()
            self.view.layoutIfNeeded()
        }
    }
}

将视图控制器的视图设置为故事板中的MyView,然后启动。在我们拨打nil电话之前,我们会反复delay。现在,图层是渲染树的一部分,所以现在和下一轮布局中,图层都有一个表示层。

另一个有趣的事情(作为读者的练习)是为图层设置动画。图层在动画期间获取不同的表示层,而在动画结束时另一个表示层。在与图层紧密配合时要牢记这一点非常重要;它的表示层不是一个常量的单个对象 - 每次重新创建时,它都会从原始层中复制。 (男孩,在我意识到之前,我感到困惑。)