swift4 CAKeyframeAnimation 不起作用

swift4 CAKeyframeAnimation not work

我在视图上使用了图层动画,但我无法在 swift4 上工作

我的视图覆盖层Class 属性

public override class var layerClass: Swift.AnyClass {
    return CoordLayer.self
}

以及自定义键创建CAKeyframeAnimation

let animation = CAKeyframeAnimation(keyPath: "moveX")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
animation.values = values
animation.keyTimes = times.map{ NSNumber(value: [=11=]) }
animation.duration = duration
animation.fillMode = kCAFillModeForwards
animation.delegate = self
self.layer.add(animation, forKey: "moveX")

CoordLayer Class

 class CoordLayer: CALayer {
override class func needsDisplay(forKey key: String) -> Bool {

        if "moveX" == key {
            return true       // ..... swift4 No call ....
        }

        return super.needsDisplay(forKey: key)
    }
}

override func display(){
      // .......some custom operations......
      // ....... swift4 No call .......
}
}

view没有动画效果swift4

KeyFrameAnimation 在 swift 4 中按预期工作:

请检查实现,您需要在实现中进行一些更正。

让我们看看。

定义控制器:

  import UIKit

 // Controller
 class ViewController: UIViewController {

 override func viewDidLoad() {
    super.viewDidLoad()
    addView()
 }

 private let myView : MyView = {
    let view = MyView()
    view.translatesAutoresizingMaskIntoConstraints = false // enable auto layout
    view.backgroundColor = .red
    return view
 }() // execute closure

 private func addView() {
    view.addSubview(myView)

    NSLayoutConstraint.activate([
         myView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), // leading
         myView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), // top
         myView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor, multiplier: 0.2), // width = 20 % of view width
         myView.heightAnchor.constraint(equalTo: myView.widthAnchor, multiplier: 1.0) // height = width
        ])
}
}

定义我的视图:

// View
class MyView : UIView {

// draw view
override func draw(_ rect: CGRect) {
    super.draw(rect)
}
// layerClass
public override class var layerClass: Swift.AnyClass {
    return CoordLayer.self
}
}

定义 CoordLayer :

// Layer
class CoordLayer : CALayer {

override func display() {
    // some custom operations
    backgroundColor = UIColor.red.cgColor // to visualize
    customAnimation() // add animation
    print("Display")
}

override class func needsDisplay(forKey key: String) -> Bool {
    if key == "transform.translation.x" {
         return true
    }
   return super.needsDisplay(forKey: key)
}

// add animation
private func customAnimation() {
    let values = [100,150,200,250]
    let times : [NSNumber] = [0.0, 0.25, 0.5, 1.0] // not necessary always

    let animation = CAKeyframeAnimation(keyPath: "transform.translation.x") // moving view along x direction
    animation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)]  // array of timing function
    animation.values = values // taking the animated property values for animation
    animation.keyTimes = times // define the timing array
    animation.duration = 5.0 // CFTimeInterval
    animation.isRemovedOnCompletion = false // do not remove the animation effect, no state changes.
    animation.fillMode = kCAFillModeForwards
    animation.delegate = self

    // add animation on coordLayer
    self.add(animation, forKey: "animation")
}
}

动画委托:

extension CoordLayer : CAAnimationDelegate {
func animationDidStart(_ anim: CAAnimation) {
    print("Animation started")
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
    print("Animation stopped")
}
}

实施中的更正:

(1) Instead of "moveX", use "transform.translation.x"
(2) Give some animation duration, animation.duration = 5.0 // CFTimeInterval
(3) animation.isRemovedOnCompletion = false , so that after animation, view will not move it's beginning position. 

你也可以在MyView中添加动画逻辑,因为你是在图层上添加动画。 Animation Delegate 可以被 MyView 符合。(由您决定)。

You can check out the implementation here.

谢谢。 :-)