Конфликтующие вызовы viewDidLoad() и другого блока кода

#swift #uiviewcontroller #uikit #viewdidload

#swift #uiviewcontroller #uikit #viewdidload

Вопрос:

Экран, о котором идет речь , я пытаюсь вызвать viewDidLoad() функцию здесь с помощью question() функции заданное количество раз и только затем вызвать код для нового контроллера представления, который нужно нажать. Но код для обоих выполняется в одно и то же точное время, так что, как только заканчивается первый раунд, запускается контроллер представления. Я пробовал использовать циклы в разных вариантах, но все эти попытки привели к аналогичным результатам. Идеи? И заранее спасибо!

 
var num1 = Int()
var num2 = Int()
var userInput = 0
    
@IBAction func numbers(_ sender: UIButton) {
        answerLabel.text = answerLabel.text!   String(sender.tag - 1)
        userInput = Int(answerLabel.text!)!
        
        answer()
    }

override func viewDidLoad() {
        super.viewDidLoad()
        
        // Views configuration
        question()
    }

func answer() {
    let answer = num1   num2
        
    if userInput == answer {
        answerLabel.text = ""
        viewDidLoad()
        let scoreVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "ScoreViewController") as! ScoreViewController
        self.navigationController?.pushViewController(scoreVC, animated: true)
    }
}


func question() {
        num1 = Int(arc4random_uniform(100))
        num2 = Int(arc4random_uniform(100))
        questionLabel.text = "(num1)     (num2)"
}
  

Комментарии:

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

2. @Deitsch Hi! Я отредактировал вопрос, а также добавил скриншот. В принципе, каждый раз, когда ответ правильный, должен быть готов новый вопрос с пустым полем ответа. Это то, что потребовало вызова viewDidLoad() внутри пользовательской функции. После завершения ответа на заданное количество вопросов (3, 5, 10 и т.д.) вы должны быть перенаправлены на другой контроллер просмотра, который отображает оценку.

Ответ №1:

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

 var num1: Int?
var num2: Int?
  

Теперь мы хотим показать вопрос. Дело в том, что viewDidLoad должен использоваться только тогда, когда — как следует из названия — загружается представление. Из-за этого мы просто создаем метод и перемещаем туда нашу логику. Вы уже это сделали, я просто переименовал вашу функцию в более говорящее имя

 viewDidLoad() {
    showNewQuestion()
}

showNewQuestion() { // previously question()
    num1 = Int(arc4random_uniform(100))
    num2 = Int(arc4random_uniform(100))
    questionLabel.text = "(num1)     (num2)"
}
  

Пока все хорошо. Теперь мы должны проверить входные данные на случайное значение в функции отправки кнопки. Вместо принудительного развертывания ( ! ) лучше безопасно развернуть ( ? ).

 @IBAction func numbers(_ sender: UIButton) {
    guard let userInput = answerLabel.text, let userInputAsInt = Int(userInput) else { 
        return 
    }
    checkAnswer(userInput: userInputAsInt) // previously answere()
}
  

Наконец, мы улучшаем вашу answer() функцию. Вам осталось подсчитать, на сколько вопросов были даны ответы. Если мы никогда не проверяем это, как программа должна знать, когда показывать результат? Чтобы устранить эту проблему, мы запоминаем, сколько вопросов было задано ( correctAnsweres ), и определяем пороговое значение, когда показывать оценку ( showScoreAfter )

 var correctAnsweres = 0
var showScoreAfter = 5 

func checkAnswer(userInputAsInt: Int) {
    let answer = num1   num2

    if userInputAsInt != answers { // early exit if answered wrong
        return
    }
    correctAnsweres  = 1
    answerLabel.text = ""
    
    //either show score
    if correctAnsweres % ShowScoreAfter == 0 {
        let scoreVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "ScoreViewController") as! ScoreViewController
        self.navigationController?.pushViewController(scoreVC, animated: true)
    }
   // or new Question
    else {
        showNewQuestion()
    }
}
  

Комментарии:

1. Большое вам спасибо! Ты потрясающий.