我正在尝试停止 CABasicAnimation
,然后重新启动它。为了在当前值停止动画,我按照 this 回答说
获取动画层的presentationLayer,读取动画属性的当前值,将该值设置为动画层,然后才移除动画。
然而,当我再次开始动画时,我得到了一个奇怪的闪烁效果,如下所示:
这是我的代码:
class ViewController: UIViewController {
let shapeView = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
var pathLayer: CAShapeLayer?
let startButton = UIButton(type: .system)
let stopButton = UIButton(type: .system)
override func viewDidLoad() {
super.viewDidLoad()
startButton.frame = CGRect(x: 50, y: 150, width: 80, height: 30)
startButton.setTitle("Start", for: .normal)
startButton.setTitleColor(UIColor.blue, for: .normal)
view.addSubview(startButton)
startButton.addTarget(self, action: #selector(start(_:)), for: .touchUpInside)
stopButton.frame = CGRect(x: 200, y: 150, width: 80, height: 30)
stopButton.setTitle("Stop", for: .normal)
stopButton.setTitleColor(UIColor.blue, for: .normal)
view.addSubview(stopButton)
stopButton.addTarget(self, action: #selector(stop(_:)), for: .touchUpInside)
view.addSubview(shapeView)
shapeView.backgroundColor = UIColor.blue
let pathLayer = CAShapeLayer()
pathLayer.path = getPentagonPath()
shapeView.layer.mask = pathLayer
self.pathLayer = pathLayer
}
@objc func start(_ sender: UIButton!) {
guard let pathLayer = pathLayer else { return }
let newPath = getConcavePentagonPath()
let animation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.path))
animation.fromValue = pathLayer.path
animation.toValue = newPath
animation.duration = 3
pathLayer.path = newPath
pathLayer.add(animation, forKey: "path")
}
@objc func stop(_ sender: UIButton!) {
guard let pathLayer = pathLayer else { return }
if let currentValue = pathLayer.presentation()?.value(forKeyPath: #keyPath(CAShapeLayer.path)) { /// get the presentationLayer for the animating layer
let currentPath = currentValue as! CGPath /// read the current value of the animated property
pathLayer.path = currentPath /// set that value to the animating layer
pathLayer.removeAllAnimations() /// remove the animation
}
}
func getPentagonPath() -> CGPath {
let pentagonPath = UIBezierPath()
pentagonPath.move(to: CGPoint(x: 50, y: 0))
pentagonPath.addLine(to: CGPoint(x: 97.55, y: 34.55))
pentagonPath.addLine(to: CGPoint(x: 79.39, y: 90.45))
pentagonPath.addLine(to: CGPoint(x: 20.61, y: 90.45))
pentagonPath.addLine(to: CGPoint(x: 2.45, y: 34.55))
pentagonPath.close()
return pentagonPath.cgPath
}
func getConcavePentagonPath() -> CGPath {
let pentagonPath = UIBezierPath()
pentagonPath.move(to: CGPoint(x: 50, y: 50))
pentagonPath.addLine(to: CGPoint(x: 97.55, y: 34.55))
pentagonPath.addLine(to: CGPoint(x: 79.39, y: 90.45))
pentagonPath.addLine(to: CGPoint(x: 20.61, y: 90.45))
pentagonPath.addLine(to: CGPoint(x: 2.45, y: 34.55))
pentagonPath.close()
return pentagonPath.cgPath
}
}