CABasicAnimation 反向(向后)

CABasicAnimation reverse(backwards)

我对这个简单的线条动画有点吃力。我想出了如何暂停它,但我需要的是能够从我调用函数 resetAnimation() 的那一刻起将动画反转回起点。

let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
    let pathLayer = CAShapeLayer()

     func lineAnimation() {

        let path = UIBezierPath()
        let screenWidth = self.view.bounds.width
        let screenHeight = self.view.bounds.height
        path.moveToPoint(CGPointMake(screenWidth, screenHeight / 2))
        path.addLineToPoint(CGPointMake(screenWidth - screenWidth, screenHeight / 2))

        self.pathLayer.frame = self.view.bounds
        self.pathLayer.path = path.CGPath
        self.pathLayer.strokeColor = UIColor.whiteColor().CGColor
        self.pathLayer.fillColor = nil
        self.pathLayer.lineWidth = 3.0
        self.pathLayer.lineCap = kCALineCapRound
        self.pathLayer.speed = 1

        self.view.layer.addSublayer(pathLayer)

        self.pathAnimation.duration = 5.0
        self.pathAnimation.fromValue = 0.0
        self.pathAnimation.toValue = 1.0

        pathLayer.addAnimation(pathAnimation, forKey: "animate")

    }

    func pauseAnimation() {

        let pausedTime = pathLayer.convertTime(CACurrentMediaTime(), fromLayer: nil)
        pathLayer.speed = 0
        pathLayer.timeOffset = pausedTime

    }

    func resetAnimation() {


    }

您只需要创建一个新动画并删除旧动画。新动画的起点将是表示层中 属性 的当前值。我还建议将形状图层的框架设置为实际贝塞尔曲线形状的边界,而不是整个视图 - 当你开始四处移动东西时,这是一个好习惯 scaling/rotating/etc。否则你将面临一堆时髦的转换或锚点更改。

我会这样做:

let pathLayer = CAShapeLayer()

// first, separate your drawing code from your animation code.
// this way you can call animations without instantiating new objects
func drawLine() {
    let path = UIBezierPath()
    // draw your path with no position translation.. move the layer
    path.moveToPoint(CGPointMake(view.bounds.width, 0))
    path.addLineToPoint(CGPointMake(0, 0))
    pathLayer.frame = path.bounds
    // this line sets the position of the layer appropriately
    pathLayer.position = view.bounds.width - pathLayer.bounds.width / 2
    pathLayer.path = path.CGPath
    pathLayer.strokeColor = UIColor.whiteColor().CGColor
    pathLayer.fillColor = nil
    pathLayer.lineWidth = 3.0
    pathLayer.lineCap = kCALineCapRound
    view.layer.addSublayer(pathLayer)
}

func lineAnimation() {
    let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
    pathAnimation.duration = 5.0
    pathAnimation.fromValue = 0.0
    pathAnimation.toValue = 1.0
    pathLayer.addAnimation(pathAnimation, forKey: "strokeEnd")

}

func reverseAnimation() {
    let revAnimation = CABasicAnimation(keyPath: "strokeEnd")
    revAnimation.duration = 5.0
    // every Core Animation has a 'presentation layer' that contains the animated changes
    revAnimation.fromValue = pathLayer.presentationLayer()?.strokeEnd
    revAnimation.toValue = 0.0
    pathLayer.removeAllAnimations()
    pathLayer.addAnimation(revAnimation, forKey: "strokeEnd")
}

请记住,您还需要设置属性以便保留动画的结束值。

您也可以使用 CAMediaTiming 协议的 autoreverses 属性,CABasicAnimation

遵守该协议