如何让我的倒数计时器重置为每次视图加载时?

Posted

技术标签:

【中文标题】如何让我的倒数计时器重置为每次视图加载时?【英文标题】:How to get my countdown timer to reset to every time the view loads? 【发布时间】:2017-07-28 21:53:29 【问题描述】:

在我的 ios 测验应用中,您有 15 秒的时间来回答问题。如果回答正确,则会出现第二个视图控制器,然后单击第二个视图控制器上的按钮将其关闭,并且第一个视图控制器会重新出现,并带有要回答的新问题。但是,当您单击问题的答案而不是单击第二个视图控制器上的按钮以关闭第二个视图控制器时,倒计时计时器就会启动。我希望倒数计时器在第二个视图控制器上的按钮被关闭并显示带有新问题的原始视图控制器时立即重置。实现这一目标的最佳方法是什么?

这是我的代码(第一个视图控制器):

import UIKit

extension ViewController: QuizCompletedDelegate 
    func continueQuiz() 
        questionTimer.text = String(counter)
    


class ViewController: UIViewController 

    //random image func
    func randomImage() 
        index = Int(arc4random_uniform(UInt32(questionImages.count)))
        questionImage.image = questionImages[index]
    

    var questionList = [String]()

    func updateCounter() 
        counter -= 1
        questionTimer.text = String(counter)

        if counter == 0             
            timer.invalidate()
            wrongSeg()
        
    

    func randomQuestion()         
        //random question
        if questionList.isEmpty 
            questionList = Array(QADictionary.keys)
            continueQuiz()            
        

        let rand = Int(arc4random_uniform(UInt32(questionList.count)))
        questionLabel.text = questionList[rand]

        //matching answer values to go with question keys
        var choices = QADictionary[questionList[rand]]!

        questionList.remove(at: rand)

        //create button
        var button:UIButton = UIButton()

        //variables
        var x = 1
        rightAnswerBox = arc4random_uniform(4)+1

        for index in 1...4
        
            button = view.viewWithTag(index) as! UIButton

            if (index == Int(rightAnswerBox))
            
                button.setTitle(choices[0], for: .normal)
            
            else 
                button.setTitle(choices[x], for: .normal)
                x += 1    
               
            randomImage()
            continueQuiz()
        
    

    let QADictionary = ["Who is Thor's brother?" : ["Atum", "Loki", "Red Norvell", "Kevin Masterson"], "What is the name of Thor's hammer?" : ["Mjolinr", "Uru", "Stormbreaker", "Thundara"], "Who is the father of Thor?" : ["Odin", "Sif", "Heimdall", "Balder"]]

    //wrong view segue
    func wrongSeg()         
        performSegue(withIdentifier: "incorrectSeg", sender: self)        
    

    //proceed screen
    func rightSeg()     
        performSegue(withIdentifier: "correctSeg", sender: self)
    

    //variables
    var rightAnswerBox:UInt32 = 0
    var index = 0

    //Question Label
    @IBOutlet weak var questionLabel: UILabel!

    //Answer Button
    @IBAction func buttonAction(_ sender: AnyObject) 
        if (sender.tag == Int(rightAnswerBox))
        
            rightSeg()
            print ("Correct!")
        

        if counter != 0 

        
        else if (sender.tag != Int(rightAnswerBox)) 
            wrongSeg()
            print ("Wrong!")
            timer.invalidate()
            questionList = []
        
    

    override func viewDidAppear(_ animated: Bool)
    
        randomQuestion()
    

    //variables
    var counter = 15

    var timer = Timer()

    @IBOutlet weak var questionTimer: UILabel!

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        timer = Timer.scheduledTimer(timeInterval: 1, target:self, selector: #selector(ViewController.updateCounter), userInfo: nil, repeats: true)        
    

第二个视图控制器的代码:

import UIKit

protocol QuizCompletedDelegate 
    func continueQuiz()


class ContinueScreen: UIViewController 

    var delegate: QuizCompletedDelegate?

    //correct answer label
    @IBOutlet weak var correctLbl: UILabel!

    //background photo
    @IBOutlet weak var backgroundImage: UIImageView!

    func backToQuiz() 
        if let nav = self.navigationController 
            nav.popViewController(animated: true)    
        
        else 
            self.dismiss(animated: true, completion: nil)
        
    

    @IBAction func `continue`(_ sender: Any) 
        backToQuiz()
        delegate?.continueQuiz()
    

    override func viewDidLoad() 
        super.viewDidLoad()
    

【问题讨论】:

如果您的第二个 ViewController 显示为 show 而不是 model,ViewDidLoad 将不会再次触发,因为视图仍在后台加载,并且从未卸载。使用 LukeSideWalkers 解决方案。 【参考方案1】:

您可以在您的第一个视图控制器上实现函数 viewDidAppear(),当您的第二个视图控制器被关闭时,该函数将自动调用,因此第一个将被看到(再次)。

所以在你的第一个视图控制器中创建这个函数:

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)

    // HERE PUT YOUR TIMER RESET
    // ...

【讨论】:

我的代码已经有这样的函数,其中包含函数 randomQuestion 你应该在他输入“PUT YOUR TIMER RESET”的地方调用那个方法,每次你返回这个控制器时都会调用它。【参考方案2】:

您的代码有问题在buttonAction。如果选择了错误的答案,你invalidate计时器。然而,如果你的答案是正确的,你就什么都不做,让它继续。

要暂停计时器,您需要使其无效,然后重新创建它。所以,你可以这样做:

//Answer Button
@IBAction func buttonAction(_ sender: AnyObject) 
    if (sender.tag == Int(rightAnswerBox))
    
        timer.invalidate() // Pause the current timer
        rightSeg()
        print ("Correct!")
    

    if counter != 0 

    
    else if (sender.tag != Int(rightAnswerBox)) 
        wrongSeg()
        print ("Wrong!")
        timer.invalidate()
        questionList = []
    

要再次创建计时器,您需要添加:

timer = Timer.scheduledTimer(timeInterval: 1, target:self, selector: #selector(ViewController.updateCounter), userInfo: nil, repeats: true)

您可以在视图出现时添加此计时器:

override func viewDidAppear(_ animated: Bool)
    
        timer = Timer.scheduledTimer(timeInterval: 1, target:self, selector: #selector(ViewController.updateCounter), userInfo: nil, repeats: true)

    

请注意,如果您在viewDidAppear 中添加计时器,则应删除viewDidLoad 中的计时器,否则您将在应用程序加载时创建两个计时器。

从 viewDidLoad 中删除计时器后,函数现在应该如下所示:

override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

 

总而言之,这里的想法是:当你得到正确答案时,你想暂停计时器(使用 timer.invalidate),然后当视图出现时,你会创建一个新的计时器。

【讨论】:

如何删除viewDidLoad 部分中的时间?

以上是关于如何让我的倒数计时器重置为每次视图加载时?的主要内容,如果未能解决你的问题,请参考以下文章

MVC 中的倒数计时器

如何在 JavaScript 中编写倒数计时器? [关闭]

表格视图单元格中的倒数计时器在滚动后显示不同的值

当另一个正在运行时,如何暂停一个倒数计时器?

如何在 kivy 中创建 60 秒倒数计时器

在列表视图中添加倒数计时器会在每个新行中重新启动