Анимация с UIBezierPath - объект фиксируется в верхнем левом углу - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь быстро создать анимацию, чтобы несколько баллонов плавали от нижней части экрана к верхней. Однако в середине анимации один из воздушных шаров фиксируется в верхнем левом углу экрана и не исчезает даже после завершения анимации.

Пожалуйста, посмотрите это видео, чтобы понять, о чем я говорю:

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()
    }

Спасибо за вашу помощь! :)

1 Ответ

0 голосов
/ 07 мая 2020

Вы должны использовать делегат, чтобы определить конец анимации и затем удалить 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?()
    }
}
...