使用 UIBezierPath 的动画 - 对象固定在左上角

Animation with UIBezierPath - Object gets fixed on the top left corner

我正在尝试在 swift 中创建一个动画,让一些气球从屏幕底部飘到顶部。但是在动画中间,其中一个气球固定在屏幕的左上角,即使动画结束也不会消失。

请观看此视频以了解我在说什么:

https://imgur.com/a/tyS0Q5u

这是我的代码。我真的不知道我做错了什么。

func presentVictoryView() {

        blackView.isHidden = false

        for _ in 0 ... 20 {

            let objectView = UIView()
            objectView.translatesAutoresizingMaskIntoConstraints = false
            objectView.frame = CGRect(x: 50, y: 50, width: 20, height: 100)
            //objectView.backgroundColor = .clear
            //objectView.alpha = CGFloat(0.9)
            objectView.isHidden = false


            let ballon = UILabel()
            ballon.translatesAutoresizingMaskIntoConstraints = false
            ballon.frame = CGRect(x: 50, y: 50, width: 20, height: 100)
            //ballon.backgroundColor = .clear
            //ballon.alpha = CGFloat(0.9)
            ballon.text = ""
            ballon.font = UIFont.systemFont(ofSize: 60)
            objectView.addSubview(ballon)


            NSLayoutConstraint.activate([
                ballon.centerXAnchor.constraint(equalTo: objectView.centerXAnchor),
                ballon.centerYAnchor.constraint(equalTo: objectView.centerYAnchor)
            ])

            blackView.addSubview(objectView)

            let randomXOffset = Int.random(in: -120 ..< 200)

            let path = UIBezierPath()
            path.move(to: CGPoint(x: 270 + randomXOffset, y: 1000))
            path.addCurve(to: CGPoint(x: 100 + randomXOffset, y: -300), controlPoint1: CGPoint(x: 300 - randomXOffset, y: 600), controlPoint2: CGPoint(x: 70 + randomXOffset, y: 300))

            let animation = CAKeyframeAnimation(keyPath: "position")
            animation.path = path.cgPath
            animation.repeatCount = 1

            animation.duration = Double.random(in: 4.0 ..< 7.0)
            //animation.timeOffset = Double(arc4random_uniform(50))

            objectView.layer.add(animation, forKey: "animate position along path")

        }

        //objectView.isHidden = true


        //self?.newGame()
    }

感谢您的帮助! :)

您应该使用委托来检测动画结束,然后删除 bubbleView。

func presentVictoryView() {

    blackView.isHidden = false

    for _ in 0 ... 20 {

        let objectView = UIView()
        objectView.translatesAutoresizingMaskIntoConstraints = false
        objectView.frame = CGRect(x: 50, y: 50, width: 20, height: 100)
        //objectView.backgroundColor = .clear
        //objectView.alpha = CGFloat(0.9)
        objectView.isHidden = false

        let ballon = UILabel()
        ballon.translatesAutoresizingMaskIntoConstraints = false
        ballon.frame = CGRect(x: 50, y: 50, width: 20, height: 100)
        //ballon.backgroundColor = .clear
        //ballon.alpha = CGFloat(0.9)
        ballon.text = ""
        ballon.font = UIFont.systemFont(ofSize: 60)
        objectView.addSubview(ballon)

        NSLayoutConstraint.activate([
            ballon.centerXAnchor.constraint(equalTo: objectView.centerXAnchor),
            ballon.centerYAnchor.constraint(equalTo: objectView.centerYAnchor)
        ])

        blackView.addSubview(objectView)

        let randomXOffset = Int.random(in: -120 ..< 200)

        let path = UIBezierPath()
        path.move(to: CGPoint(x: 270 + randomXOffset, y: 1000))
        path.addCurve(to: CGPoint(x: 100 + randomXOffset, y: -300), controlPoint1: CGPoint(x: 300 - randomXOffset, y: 600), controlPoint2: CGPoint(x: 70 + randomXOffset, y: 300))

        let animation = CAKeyframeAnimation(keyPath: "position")
        animation.path = path.cgPath
        animation.repeatCount = 1

        // add these
        animation.fillMode = .forwards
        animation.isRemovedOnCompletion = false
        let delegate = BubbleAnimDelegate()
        delegate.didFinishAnimation = {
            objectView.removeFromSuperview()
        }
        animation.delegate = delegate
        // upto here

        animation.duration = Double.random(in: 4.0 ..< 7.0)
        //animation.timeOffset = Double(arc4random_uniform(50))

        objectView.layer.add(animation, forKey: "animate position along path")

    }
    //objectView.isHidden = true
    //self?.newGame()
}

class BubbleAnimDelegate: NSObject, CAAnimationDelegate {

    var didFinishAnimation: (()->Void)?

    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        didFinishAnimation?()
    }
}