我正在使用 CALayers,我想在动画运行时检索有关图层子图层状态的一些信息。现在我知道我可以通过调用mySublayer.presentation()
并访问返回层的属性从子层的表示层检索信息。
但是,返回值是可选值,并且实际上相对频繁地返回nil
。在我的特殊情况下,调用发生在我的层的layoutSublayers()
内(我想要的信息的层的超级层(。
这就是为什么我想知道:一个层什么时候有表示层,什么时候没有表示层? 不幸的是,我在Apple的文档中找不到任何有关此内容的内容。
多谢!
图层何时具有表示层
当它是渲染树的一部分时。图层始终作为其表示图层呈现在屏幕上。
您获得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
电话。现在该层是渲染树的一部分,因此现在和下一轮布局中,该层都有一个表示层。
另一个有趣的事情(留给读者练习(是动画图层。该层在动画期间获取不同的表示层,并在动画结束时获取另一个表示层。在与图层密切合作时,牢记这一点非常重要;它的表示层不是一个恒定的单一对象 - 每次重新创建时,它都会从原始层复制。(男孩,在我意识到这一点之前,我是不是很困惑。