Swift:测验应用程序,“超时!”计时器= 0时的消息

时间:2018-08-08 06:50:43

标签: ios swift timer

我正在构建一个测验应用程序,用户可以在15秒内回答问题。 我是新手,所以我不确定在timer.secondsRemaining == 0时如何显示超时消息: questionField.text =“超时!” 并禁用带有答案的按钮。

我在单独的swift文件中设置了一个计时器类:

import Foundation

class questionTimer {
    var timer = Timer()
    var secondsRemaining: Float = 15
    var isOn = false

func start() {
    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
    isOn = true
    print("time started")
}

@objc func updateCounter() {
    secondsRemaining -= 1
    print(secondsRemaining)
    if secondsRemaining == 0 {
        timer.invalidate()
        print("time over")
    }
}

func reset() {
    secondsRemaining = 15
    timer.invalidate()
    isOn = false
    print("time stopped")
}

}

我的viewController看起来像这样:

import UIKit
import AudioToolbox

class ViewController: UIViewController {

// MARK: - Properties

let gameManager = GameManager()
let timer = questionTimer()
var buttons = [UIButton]()

// MARK: - Outlets

@IBOutlet weak var header: UIView!
@IBOutlet weak var questionTracker: UILabel!
@IBOutlet weak var questionField: UILabel!
@IBOutlet weak var option1Button: UIButton!
@IBOutlet weak var option2Button: UIButton!
@IBOutlet weak var option3Button: UIButton!
@IBOutlet weak var option4Button: UIButton!
@IBOutlet weak var playAgainButton: UIButton!

// MARK: - Actions

@IBAction func checkANswer(_ sender: UIButton) {
    // Disable all buttons
    for button in buttons {
        button.isEnabled = false
    }

    // Check the answer selected and display feedback
    if gameManager.isCorrect(sender.tag) {
        questionField.text = "Correct!"
        playCorrectSound()
        sender.titleLabel?.font = UIFont.boldSystemFont(ofSize: 15)
    } else {
        questionField.text = "Sorry, that's not it."

        // Highlight correct answer
        let correctAnswer = self.gameManager.quiz.questions[self.gameManager.indexOfSelectedQuestion].correctAnswer
    }

    // reset timer
    timer.reset()

    // call next round
    loadNextRound(delay: 2)
}

@IBAction func playAgain(_ sender: UIButton) {
    // Reset game manager properties to 0
    gameManager.correctQuestions = 0
    gameManager.questionsAsked = 0

    // call next round
    nextRound()
}

// MARK: - Helpers

func displayAnswers() {
    // Reset display without any button
    hideAllButtons()
    resetButtonsStyle()
    buttons = []

    // create buttons depending on number of answers of the selected question
    let questionSelected = gameManager.quiz.questions[gameManager.indexOfSelectedQuestion]
    let numOfAnswers = questionSelected.possibleAnswers.count

    switch numOfAnswers {
    case 1: buttons += [option1Button]
    case 2: buttons += [option1Button, option2Button]
    case 3: buttons += [option1Button, option2Button, option3Button]
    case 4: buttons += [option1Button, option2Button, option3Button, option4Button]
    default: print("This question has no answers")
    }

    for button in buttons {
        let index = button.tag
        button.setTitle(questionSelected.possibleAnswers[index], for: .normal)
        button.isHidden = false
        button.isEnabled = true
    }
}

func displayQuestion() {
    // Select random question
    let questionSelected = gameManager.getRandomQuestion()

    // Set labels text
    questionField.text = questionSelected.question
    questionTracker.text = "Question \(gameManager.questionsAsked) of \(gameManager.questionsPerRound)"

    // Display answers
    displayAnswers()

    // HIde play button
    playAgainButton.isHidden = true

    // Start timer
    timer.start()
}

func displayScore() {
}

func nextRound() {
    resetButtonsStyle()
    if gameManager.questionsAsked == gameManager.questionsPerRound {
        // Game is over
        displayScore()
        gameManager.previousQuestionIndexes = []
    } else {
        // Continue game
        displayQuestion()
    }
}

func loadNextRound(delay seconds: Int) {
    // Converts a delay in seconds to nanoseconds as signed 64 bit integer
    let delay = Int64(NSEC_PER_SEC * UInt64(seconds))
    // Calculates a time value to execute the method given current time and delay
    let dispatchTime = DispatchTime.now() + Double(delay) / Double(NSEC_PER_SEC)

    // Executes the nextRound method at the dispatch time on the main queue
    DispatchQueue.main.asyncAfter(deadline: dispatchTime) {
        self.nextRound()
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    displayQuestion()
    questionTracker.text = "Question \(gameManager.questionsAsked) of \(gameManager.questionsPerRound)"
}

}

由于updateCounter()方法位于单独的文件中,如何使其在视图控制器中更改questionField.text?

如果我将其放在viewController中,将无法正常工作:

// Time out
    if timer.secondsRemaining == 0 {
        print("time out")
        questionField.text = "Time out!"
        for button in buttons {
            button.isEnabled = false
        }
        timer.reset()

1 个答案:

答案 0 :(得分:1)

一个简单的解决方案是观察secondsRemaining

var secondsRemaining: Float = 15 {
    didSet {
        if secondsRemaining == 0 {
            // update UI
        } 
   }
}

您也可以为Int更改它