CALayer 路径动画在停止和重新启动时闪烁

时间:2020-12-28 03:06:39

标签: ios swift cabasicanimation

我正在尝试停止 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
    }
}

0 个答案:

没有答案
相关问题