let flyRight = CABasicAnimation(keyPath: "position.x")
flyRight.toValue = view.bounds.size.width/2
flyRight.duration = 0.5
flyRight.fromValue = -view.bounds.size.width/2
flyRight.fillMode = kCAFillModeBoth
flyRight.beginTime = CACurrentMediaTime() + 3.4
password.layer.position.x = view.bounds.size.width/2
password.layer.addAnimation(flyRight, forKey: nil)
我的问题是:在添加动画之前,我怎么可能首先将图层放在最终位置,但是当应用程序启动时,我在动画开始之前没有看到它?相反,动画按预期在3.4秒后工作。
我的意思是,iOS如何知道首先它需要运行动画然后才将图层放到它的最终位置?
答案 0 :(得分:2)
它与UI更改的应用方式有关。当您对UI对象进行更改时,在您的代码返回并且事件循环运行之前,该更改不会呈现给屏幕。
当发生这种情况时,系统会将您的视图移动到它的最终位置,但是后面的ACTUAL视图/图层层次结构将被覆盖在顶部绘制的新图层(称为表示层)。表示层是动画中的像素显示在屏幕上的位置。这就是你所看到的。
当动画结束时,隐藏/删除表示层(不确定是哪个)并显示实际的图层内容。此时图层处于最终位置,所以一切看起来都是正确的。
答案 1 :(得分:2)
这是因为有一个presentationLayer
和一个modelLayer
动画显示和修改presentationLayer
,所以presentationLayer
就像鬼一样。
你可能知道UIView实例以及支持图层的NSViews会修改它们的图层以将渲染委托给强大的Core 动画框架。但是,理解这一点很重要 动画添加到图层时,不要修改其属性 直。 相反,Core Animation维护两个并行层次结构:模型层树和表示层树。 前者中的层反映了层的众所周知的状态,后者中的层仅接近于飞行中的值 动画。 考虑向视图添加淡出动画。如果您在动画期间的任何时候检查图层的不透明度值,那么 最有可能不会获得与屏幕上的内容相对应的不透明度。 相反,您需要检查表示层以获得正确的 结果。 虽然您可能无法直接设置表示层的属性,但使用其当前值来创建新属性会很有用 动画或在动画拍摄时与图层交互 地点。 通过使用 - [CALayer presentationLayer]和 - [CALayer modelLayer],您可以轻松地在两个层次结构之间切换。
您可以在https://www.objc.io/issues/12-animations/animations-explained/
找到更多信息我希望这有助于你