【问题标题】:swift4 CAKeyframeAnimation not workswift4 CAKeyframeAnimation 不起作用
【发布时间】:2017-12-08 03:42:59
【问题描述】:

我在视图上使用了图层动画,但我无法在 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 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

【问题讨论】:

  • 我已经解决了这个问题。 CoordLayer Inherit CALayer , CALayer 继承 NSObject swift4 NSObject 调用 swift String (例如自定义键 "movex") , CoordLayer 需要@objcMembers 类 CoordLayer: CALayer,它工作!

标签: animation layer swift4


【解决方案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
        ])
}
}

定义我的视图:

// 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
}
}

定义坐标层:

// 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.

谢谢。 :-)

【讨论】:

  • 谢谢,使用“transform.translation.x”代替“moveX”是可行的,但在 swift4 之前我使用自定义键并覆盖类 func needsDisplay(forKey key: String) -> Bool 自定义键回报就是工作
  • 我的视图自定义动画,使用“transform.translation.x”不起作用,因为视图是 MapPinView,我将坐标转换为视图农场,并使用图层动画使引脚视图平滑移动覆盖 func display() { conver coordiante set layer position }
  • 我需要自定义 keypath 并覆盖类 func needsDisplay(forKey key: String) -> Bool custom key reutrn ture ,func display() 需要一直调用
  • 我已经解决了这个问题。 CoordLayer Inherit CALayer , CALayer 继承 NSObject swift4 NSObject 调用 swift String (例如自定义键 "movex") , CoordLayer 需要@objcMembers 类 CoordLayer: CALayer,它工作!
  • 是的,@objc 是必需的。谢谢。
猜你喜欢
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多