Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何让我的倒计时重置为每次加载视图时的倒计时?_Ios_Swift_Timer_Delegates_Viewcontroller - Fatal编程技术网

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

Ios 如何让我的倒计时重置为每次加载视图时的倒计时?,ios,swift,timer,delegates,viewcontroller,Ios,Swift,Timer,Delegates,Viewcontroller,在我的iOS问答应用程序中,你有15秒的时间回答问题。如果回答正确,则会出现第二个视图控制器,然后单击第二个视图控制器上的按钮将其取消,并且第一个视图控制器会重新出现,并显示一个新问题以供回答。但是,只要单击问题的答案,倒计时计时器就会启动,而不是单击第二视图控制器上的按钮以关闭第二视图控制器时。我希望倒数计时器在第二个视图控制器上的按钮被取消并用新问题显示原始视图控制器后立即重置。最好的办法是什么 以下是我的代码(第一视图控制器): 第二视图控制器的代码: import UIKit prot

在我的iOS问答应用程序中,你有15秒的时间回答问题。如果回答正确,则会出现第二个视图控制器,然后单击第二个视图控制器上的按钮将其取消,并且第一个视图控制器会重新出现,并显示一个新问题以供回答。但是,只要单击问题的答案,倒计时计时器就会启动,而不是单击第二视图控制器上的按钮以关闭第二视图控制器时。我希望倒数计时器在第二个视图控制器上的按钮被取消并用新问题显示原始视图控制器后立即重置。最好的办法是什么

以下是我的代码(第一视图控制器):

第二视图控制器的代码:

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()
    }
}

代码的问题出现在
按钮操作中
。如果选择了错误的答案,将使计时器无效。但是,如果您的答案是正确的,您对计时器不做任何操作,并允许它继续

要暂停计时器,需要先使其无效,然后重新创建。所以,你能做的是:

//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),然后当视图出现时,您将创建一个新的计时器。

代码的问题在于
按钮操作。如果选择了错误的答案,将使计时器无效。但是,如果您的答案是正确的,您对计时器不做任何操作,并允许它继续

要暂停计时器,需要先使其无效,然后重新创建。所以,你能做的是:

//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),然后当视图出现时,您将创建一个新的计时器。

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

因此,在第一个视图控制器中创建此函数:

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)        
    }
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

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

您可以在第一个视图控制器上实现函数viewdispect(),当第二个视图控制器被解除时,将自动调用此函数,因此第一个视图控制器将被(再次)看到

因此,在第一个视图控制器中创建此函数:

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)        
    }
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

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

如果第二个ViewController显示为“显示”,而不是“模型”,则ViewDidLoad将不会再次激发,因为视图仍在后台加载,并且从未卸载。使用LukeSideWalkers解决方案。如果第二个ViewController显示为show,而不是model,ViewDidLoad将不会再次激发,因为该视图仍在后台加载,并且从未卸载。使用LukeSideWalkers解决方案。我的代码已经有这样的函数,其中包含函数RandomQuestion。你应该在他键入“放置计时器重置”的地方调用该方法,每次你回到这个控制器时,它都会被调用。我的代码已经有了这样一个函数,其中包含了函数randomQuestion,你应该在他键入“放置你的计时器重置”的地方调用该方法,每次您返回此控制器时都会调用它。我如何删除
viewDidLoad
部分中的时间?我如何删除
viewDidLoad
部分中的时间?