swift4 CAKeyframeAnimation不起作用

时间:2017-12-08 03:43:00

标签: animation layer swift4

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

我的视图覆盖了layerClass属性

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: $0) }
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 .......
}
}

视图没有动画效果swift4

1 个答案:

答案 0 :(得分:1)

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
        ])
}
}

定义MyView:

// 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中添加动画逻辑,因为您要在图层上添加动画。动画代表可以通过MyView来实现。(它取决于你)。

You can check out the implementation here.

感谢。 : - )

abc