我正在关注this教程。可以找到代码段here。在某些动画中,动画会直接发送到UIView
。就像下面的代码片段一样。
问题1:这个UIView是什么类的属性?或者是我们在UIView上传达了屏幕上的所有内容,在代码块中做了什么?我只是想了解我们在这里传达的属性......
protocol Flashable {}
extension Flashable where Self: UIView {
func flash() {
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn, animations: {
self.alpha = 1.0
}) { (animationComplete) in
if animationComplete == true {
UIView.animate(withDuration: 0.3, delay: 2.0, options: .curveEaseOut, animations: {
self.alpha = 0.0
}, completion: nil)
}
}
}
}
^^^我没有得到UIView.animate
部分。 ^^^
对某些人而言,它并没有直接发送给UIView
。
extension Jitterable where Self: UIView {
func jitter() {
let animation = CABasicAnimation(keyPath: "position")
animation.duration = 0.05
animation.repeatCount = 5
animation.autoreverses = true
animation.fromValue = NSValue(cgPoint: CGPoint.init(x: self.center.x - 5.0, y: self.center.y))
animation.toValue = NSValue(cgPoint: CGPoint.init(x: self.center.x + 5.0, y: self.center.y))
layer.add(animation, forKey: "position")
}
}
^^^上面的代码更容易理解^^^
但是当你想要打电话给他们时,你会这样做:
errorLabel.flash()
errorLabel.jitter()
问题2:两种动画的编写方式之间的区别是什么?
答案 0 :(得分:3)
动画块在所有视图中都是全局的。给定的动画块是免费的(并且被鼓励)以同时为想要的多个视图设置动画。所以这自然是一个全球性的"功能,与任何特定视图无关。
在面向对象的编程中,通常实现" global"在一些相关的类上充当静态/类方法。这改善了名称间距(偶尔还有其他好处,例如访问类数据)。这就是发生在这里的所有事情。 UIView
是一个方便且富有表现力的地方,可以嵌套全局animate(withDuration:...)
方法。但这些方法实际上只是全局功能。没有严格的规则他们甚至不得不为观点制作动画。
在您的CABasicAnimation
代码中,还创建了隐式全局CATransaction
,其中包含了所有当前动画。所以"更容易理解"版本也有点神奇,隐藏了一些比较复杂的部分(如果你不理解它,可能会咬你一些)。实际上,UIView
版本更加明确,特别是如果您将多个内容组合在一起。这是添加UIView
包装器的一个原因,以及为什么它通常是动画视图的更好方法。
答案 1 :(得分:1)
animate(withDuration:animations:completion:)函数是UIView
的类型方法。
这意味着您可以在第一个代码段中看到类型UIView
上的函数。您可以在Swift Language Guide
此功能的第二个参数是您要执行的动画。这可以是单个视图上的动画(在本例中为self
)或任何其他数量的视图和动画。
第二版动画是CABasicAnimation。您可以设置动画,然后将其附加到所需的特定图层。
正如文档所说,CABasicAnimation是
为图层属性提供基本单关键帧动画功能的对象。