Нажмите «Жест» не работает на Circle Swift

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

import UIKit
import AVFoundation

class Demogame: UIViewController {

    @IBOutlet weak var scoreLabel: UILabel!

    var score = 0
    var isGameOver = false

    override func viewDidLoad() {
        super.viewDidLoad()
        startGame()
    }

    func startGame() {
        score = 0
        scoreLabel.text = "Score: \(score)"
        isGameOver = false

        // Create a timer to spawn circles
        Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in
            if !self.isGameOver {
                self.spawnCircle()
            } else {
                timer.invalidate()
            }
        }
    }

    func spawnCircle() {
        let circleSize = CGSize(width: 50, height: 50)
        let circleView = UIView(frame: CGRect(origin: CGPoint(x: CGFloat.random(in: 50...view.frame.width - circleSize.width - 50),
                                                              y: CGFloat.random(in: 100...view.frame.height - circleSize.height - 50)),
                                              size: circleSize))

        circleView.backgroundColor = UIColor.random()
        circleView.layer.cornerRadius = circleSize.width / 2
        view.addSubview(circleView)

        // Add a tap gesture recognizer to each circle
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
        circleView.addGestureRecognizer(tapGesture)

        // Animate the circle's appearance and disappearance
        UIView.animate(withDuration: 3.0, animations: {
            circleView.alpha = 0.0
        }) { (completed) in
            if completed {
                circleView.removeFromSuperview()
            }
        }
    }

    @objc func handleTap(_ sender: UITapGestureRecognizer) {
        if isGameOver {
            return
        }

        if let tappedView = sender.view {
            tappedView.removeFromSuperview()
            score += 1
            scoreLabel.text = "Score: \(score)"
        }
    }
}

extension UIColor {
    static func random() -> UIColor {
        return UIColor(
            red: CGFloat.random(in: 0.0...1.0),
            green: CGFloat.random(in: 0.0...1.0),
            blue: CGFloat.random(in: 0.0...1.0),
            alpha: 1.0
        )
    }
}

Вопрос: Как нажать жест, работающий по кругам, и повысить уровень очков?

Может кто-нибудь объяснить мне, как это сделать, я пробовал использовать приведенный выше код, но пока безрезультатно. Пожалуйста, поправьте меня, если я делаю неправильно.

Любая помощь будет принята с благодарностью


1
71
2

Ответы:

Решено

Виды — кнопки, метки, изображения, простые представления и т. д. — не получают касаний, когда .alpha меньше 0.01.

Что может быть неочевидно, так это то, что когда мы пишем такой блок анимации:

UIView.animate(withDuration: 3.0, animations: {
    circleView.alpha = 0.0
})

UIKit немедленно оценивает инструкции внутри блока, а затем вычисляет визуальный эффект анимации.

Итак, как только эта анимация запускается, UIKit считает, что circleView имеет .alpha из 0.0 - поэтому нет события касания / жеста касания.

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

Вы можете это исправить, установив для параметров анимации значение .allowUserInteraction.

Если вы измените свой блок анимации на это:

UIView.animate(withDuration: 3.0, delay: 0.0, options: .allowUserInteraction, animations: {
    circleView.alpha = 0.05
}, completion: { b in
    if b {
        circleView.removeFromSuperview()
    }
})

Теперь вы сможете нажимать на круги.


Перепишите блок анимации следующим образом:

UIView.animate(withDuration: 3.0,
               delay: 0.0,
               options: .allowUserInteraction
               animations: { circleView.backgroundColor = .clear },
               completion: { completed in
        if completed {
            circleView.removeFromSuperview()
        }
})
  1. Установка альфа-канала представления на ноль отключает проверку попадания, поэтому вместо этого используйте чистый цвет.
  2. Добавьте в анимацию опцию «разрешить взаимодействие с пользователем».