当以模态方式显示另一个vc时,CABasicAnimation完成

时间:2017-09-07 12:15:34

标签: ios swift swift3 cabasicanimation

我使用以下方式暂停/恢复动画

func pauseAnimation(){
  var pausedTime = layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
  layer.speed = 0.0
  layer.timeOffset = pausedTime
}

func resumeAnimation(){
  var pausedTime = layer.timeOffset
  layer.speed = 1.0
  layer.timeOffset = 0.0
  layer.beginTime = 0.0
  let timeSincePause = layer.convertTime(CACurrentMediaTime(), fromLayer: nil) - pausedTime
  layer.beginTime = timeSincePause
}

只要目前呈现ViewController,它就像魅力一样。

当我以模态方式呈现另一个视图控制器然后将其关闭时,无论在当前/解除操作期间经过了多长时间,动画都会完成。

您有什么建议可能会发生这种情况吗?怎么解决?我想补充一点,所有其他视图都保持其状态,只有动画完成。

编辑:

我只是发现它发生了暂停/恢复的问题 - 在这种情况下,正在进行的动画也会完成。

这是我的代码,显示动画实现

import Foundation

import UIKit

class CircleView: UIView {

var circleLayer: CAShapeLayer!

@IBOutlet var view: UIView!


@IBOutlet weak var progressLabel: UILabel!

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    Bundle.main.loadNibNamed("CircleView", owner: self, options: nil)
    self.addSubview(view)
    view.frame = self.bounds

}

override func awakeFromNib() {
        super.awakeFromNib()
        setupAppearance()

}

func setupAppearance() {
    progressLabel.textColor = UIColor.textColor
    progressLabel.font = UIFont.textTimerClock
}


func setup(progress:Double, clockwise:Bool) {

    self.backgroundColor = UIColor.clear
    var strokeColor = UIColor.positiveProgressColor
    if !clockwise { strokeColor = UIColor.positiveProgressColor }

    // Use UIBezierPath as an easy way to create the CGPath for the layer.
    // The path should be the entire circle.
    let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(.pi * 2 * progress), clockwise: clockwise)

    // Setup the CAShapeLayer with the path, colors, and line width
    circleLayer = CAShapeLayer()
    circleLayer.path = circlePath.cgPath
    circleLayer.fillColor = UIColor.clear.cgColor
    circleLayer.strokeColor = strokeColor.cgColor
    circleLayer.lineWidth = 8.0;

    // Don't draw the circle initially
    circleLayer.strokeEnd = 0.0

    // Add the circleLayer to the view's layer's sublayers
    layer.addSublayer(circleLayer)

    //add grey path
    let greyCircleLayer = CAShapeLayer()

    let greyCirclePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(.pi * 2.0), clockwise: true)

    greyCircleLayer.path = greyCirclePath.cgPath
    greyCircleLayer.fillColor = UIColor.clear.cgColor
    greyCircleLayer.strokeColor = UIColor.appLightGrey.cgColor
    greyCircleLayer.lineWidth = 1.0;

    // Don't draw the circle initially
    circleLayer.strokeEnd = 0.0

    // Add the circleLayer to the view's layer's sublayers
    layer.insertSublayer(greyCircleLayer, below: circleLayer)
    if progressLabel != nil {

        progressLabel.text = "10"}
}

func pauseAnimation(){
    let pausedTime = circleLayer.convertTime(CACurrentMediaTime(), from: nil)
    circleLayer.speed = 0.0
    circleLayer.timeOffset = pausedTime
}

func resumeAnimation(){
    let pausedTime = circleLayer.timeOffset
    circleLayer.speed = 1.0
    circleLayer.timeOffset = 0.0
    circleLayer.beginTime = 0.0
    let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
    circleLayer.beginTime = timeSincePause
}


func animateCircle(duration: TimeInterval, color: UIColor) {
    // We want to animate the strokeEnd property of the circleLayer
            circleLayer.strokeColor = color.cgColor
    let animation = CABasicAnimation(keyPath: "strokeEnd")

    // Set the animation duration appropriately
    animation.duration = duration

    // Animate from 0 (no circle) to 1 (full circle)
    animation.fromValue = 0
    animation.toValue = 1

    // Do a linear animation (i.e. the speed of the animation stays the same)
    animation.timingFunction = CAMediaTimingFunction(name: kCAAnimationLinear)

    // Set the circleLayer's strokeEnd property to 1.0 now so that it's the
    // right value when the animation ends.
    circleLayer.strokeEnd = 1.0

    // Do the actual animation
    circleLayer.add(animation, forKey: "animateCircle")
}
}

另外值得一提的是:init(),awakeFromNib()没有被再次调用,所以情况并非如此。

另一个:推送VC而不是模态呈现也是如此。

1 个答案:

答案 0 :(得分:0)

通常,当您显示另一个视图控制器时,将从窗口中删除当前视图控制器的视图。这也将从其图层中删除所有待处理的动画,并且使用false调用任何现有的动画完成处理程序,因为动画未完成(另请参阅https://stackoverflow.com/a/21200504/2352344)。

要在返回视图控制器后继续动画,您应该在viewWillAppear中重建动画对象。