Swift4 CAShapeLayer动画中KeyPath的使用方法

How to use Swift 4 KeyPath in CAShapeLayer animation

如果我写 Swift 3 代码,它看起来像这样:

let animation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.path))

但我尝试对 keyPath 使用 Swift 4 个新语法,我得到:

let keyPath = \CAShapeLayer.path
let animation = CABasicAnimation(keyPath: keyPath) // error line

> Error: Cannot convert value of type 'ReferenceWritableKeyPath' to expected argument type 'String?'

在 swift 4 的这种情况下如何使用密钥路径?

至于现在 CABasicAnimation 仍然使用旧的 String keyPaths 所以你仍然应该使用 #keyPath(CAShapeLayer.path) 即使你正在使用 Swift 4.

Apple 将来可能会更新其所有 API,以使用这些更安全的密钥路径引用。但是现在您只能使用 "unsafe" 字符串。

是的,可以使用 swift 键路径。 喜欢:

extension UIView {

func animateLayer<Value>(_ keyPath: WritableKeyPath<CALayer, Value>, to value:Value, duration: CFTimeInterval) {

    let keyString = NSExpression(forKeyPath: keyPath).keyPath
    let animation = CABasicAnimation(keyPath: keyString)
    animation.fromValue = self.layer[keyPath: keyPath]
    animation.toValue = value
    animation.duration = duration
    self.layer.add(animation, forKey: animation.keyPath)
    var thelayer = layer
    thelayer[keyPath: keyPath] = value
}
}

用法如下:

animateLayer(\.shadowOffset, to: CGSize(width: 3, height: 3), duration:1)
animateLayer(\.shadowOpacity, to: 0.4, duration: 1)

它没有经过全面测试。但对我有用。

对于 Swift 5 你可以使用类似这样的东西:

let ba: CABasicAnimation = CABasicAnimation(keyPath: #keyPath(CAEmitterLayer.emitterPosition))
ba.fromValue = topMid
ba.toValue = topMid.offsetBy(dx: dx, dy: dy)
ba.duration = 6
ba.autoreverses = true
ba.repeatCount = .infinity
snowflakeEmitterLayer.add(ba, forKey: nil)