【问题标题】:When does a CALayer have a presentationLayer?CALayer 什么时候有presentationLayer?
【发布时间】:2018-01-25 04:02:17
【问题描述】:

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

但是,返回值是一个可选值,并且实际上返回 nil 的频率相对较高。在我的特殊情况下,调用发生在我层的layoutSublayers() 内部(我想要的信息层的超级层)。

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

非常感谢!

【问题讨论】:

  • 您在Apple docs 中错过了这个吗? While an animation is in progress, you can retrieve this object and use it to get the current values for those animations.
  • 正如您所指出的,我知道它存在于动画期间。在我看来,有时在动画过程中我仍然得到零。不过,我可能在我的代码中遗漏了一些东西,所以我会再次检查。

标签: swift macos calayer appkit presentation-layer


【解决方案1】:

层什么时候有表示层

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

您收到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 电话。现在该层是渲染树的一部分,所以现在和下一轮布局中,该层有一个表示层。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 2011-09-28
    • 2011-09-06
    • 2010-12-26
    • 2012-08-18
    相关资源
    最近更新 更多