Возможно, ошибка связана с DispatchQueue.main.asyncAfter в действии UIButton при спаме / быстром нажатии и повторном нажатии - PullRequest
1 голос
/ 28 апреля 2020

Проект можно клонировать здесь https://github.com/randomjuniorburger/quizapp

У меня есть UIButton, который связан с действием, которое использует DispatchQueue.main.asyncAfter. Приложение работает хорошо, за исключением случаев, когда пользователь спамит / нажимает на кнопки «Правда» / «Ложь» или нажимает или запускает любую из них много раз подряд за короткий промежуток времени, что приводит к перекрытию задержек (задержек) и позволяет пользователю получить более высокий балл, чем это должно быть возможно (например, только 8 вопросов имеют ответ «Истина», но оценка 10 возможна из-за ошибки, если кнопка «Истина» является спамом)

Мне интересно, как я могу это исправить / предотвратить?

NB. Я начинающий и увлеченный разработчик Swift. Этот проект - моя попытка воссоздать модуль курса, который я беру с Анжелой Ю.

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

Код только для кнопки:

@IBAction func answerPressed(_ sender: UIButton) {

    let userAnswer = sender.currentTitle
    let actualAnswer = quizArray[questionNumber].answer

    if questionNumber < (quizArray.count - 1) {
        self.questionNumber += 1
        updateProgressBar()
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
            self.questionLabel.text = self.quizArray[self.questionNumber].text
        }

        if userAnswer == actualAnswer {
            questionLabel.text = "✅"
            score += 1
            scoreLabel.text = String("Score: \(score) / 12")

        } else {
            questionLabel.text = "❌"
        }

    } else if questionNumber == (quizArray.count - 1) && questionLabel.text != "End of Quiz" {
        if userAnswer == actualAnswer {
            questionLabel.text = "✅"
            score += 1
            scoreLabel.text = String("Score: \(score) / 12")
        } else {
            questionLabel.text = "❌"
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
            self.progressBar.progress = Float(1)
            print("No more questions")
            self.questionLabel.text = "End of Quiz"
        }
    }

}

1 Ответ

0 голосов
/ 28 апреля 2020

Здесь возможное решение - просто не позволяйте пользователю генерировать нежелательные нажатия

sender.isEnabled = false // don't allow action until question updated
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
    self.questionLabel.text = self.quizArray[self.questionNumber].text
    sender.isEnabled = true // << allow user interaction
}

в секунду сделать то же самое

...