Swift NSTiimer 不遵循指定的间隔 [英] Swift NSTiimer not following specified Interval

查看:74
本文介绍了Swift NSTiimer 不遵循指定的间隔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个测验应用程序,该应用程序在计时器到期时(即 10 秒,我希望计时器的间隔为 1 秒)为每个问题提供一个计时器,它会自行重置并获取下一个问题并再次使用计时器从 10 点重新开始...但我的问题是,当加载第一个问题时,计时器不遵循固定间隔,它显示间隔为 2 ... 即 10,8,6 .. 然后对于第二个问题,它跳为 3secs 间隔,同样间隔增加.

I am trying to create a quiz app which has a timer for each question when the timer expires (i.e. 10 seconds and I want Timer to have an interval of 1 sec) it resets it self and next question is fetched and Timer again restart from 10... But my issue is the timer doesn't follow a fixed interval when first question is loaded it shows interval of 2 ... i.e. 10,8,6 .. and then for second question it makes jump for 3 secs interval and similarly the interval increases.

导入 UIKit

class ViewController: UIViewController {

    let allQuestions = QuestionsBundle()
    var pickedAnswer : Int = 0
    var questionCounter = 0
    var score : Int = 0
    var timer: Timer!
    
    
    
    
    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var countDownLabel: UILabel!
    
    @IBOutlet weak var ansLbl1: UILabel!
    @IBOutlet weak var ansLbl2: UILabel!
    @IBOutlet weak var ansLbl3: UILabel!
    @IBOutlet weak var ansLbl4: UILabel!
    
    
    
    @IBOutlet weak var checkBox1: CheckBox!
    @IBOutlet weak var checkBox2: CheckBox!
    @IBOutlet weak var checkBox3: CheckBox!
    @IBOutlet weak var checkBox4: CheckBox!
    
    var checkBoxlist : [CheckBox] = []
 
    
    @IBAction func correct_Answer_Checbox_Btn(_ sender: AnyObject) {
        //print("\(sender.tag) <==> \(String(describing: question?.correctAnswer))")
        
        updateCheckBoxes(sender: sender)
        
        if sender.tag == question?.correctAnswer{
           question?.isAnswerCorrect = true
            question?.selectedAnswer = sender.tag
            //score = score + 1
            
            
        }
            
        else {
            question?.isAnswerCorrect = false
        }
        
    }
    
    func updateCheckBoxes(sender: AnyObject){
        for checkBoxItem in checkBoxlist{
            if checkBoxItem.tag != sender.tag {
                checkBoxItem.isChecked = false
            }
        }
        
    }
    
    @IBOutlet weak var nextButton: UIButton!
    @IBAction func nextBtnClicked(_ sender: AnyObject) {
        do{
            try handleNextQuestion()
        }
        catch{
               moveToResultView()
        }
       
        
    }
    
    func handleNextQuestion() throws {
        nextQuestion()
        if questionCounter == allQuestions.list.count-1{
            finishButton.isHidden = false
            nextButton.isHidden = true
            //scoreLbl.text = "\(score)"
        }
    }
    
    var question : Question?
    
    var countTime = 10.0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        finishButton?.isHidden = true
        checkBoxlist = fetchCheckBoxList()
        question = fetchQuestion()
        setQuizView(question: question!)
        
        
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    
  
    
    // set all questions in a function
    
    @objc func update() {
        if(countTime > 0) {
            countTime = countTime - 1
            self.countDownLabel.text = String(countTime)
        }else{
            timer.invalidate()
            countTime = 10.0
            do{

                try handleNextQuestion()

            }
            catch{
                   moveToResultView()
            }
            
        }
    }
 
    
   
    func startTimer() {
        timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true)
    }
    func setQuizView(question:Question)  {
        self.countDownLabel.text = "10"
        
        startTimer()
        questionLabel.text =  question.questionText
        ansLbl1.text =  question.answer1
        ansLbl2.text =  question.answer2
        ansLbl3.text =  question.answer3
        ansLbl4.text =  question.answer4
        
        if question.selectedAnswer == Constants.DEFAULT_ANSWER {
            for checkBoxItem in checkBoxlist{
                checkBoxItem.isChecked = false
            }
            
        }
        
    }
    
    
    @IBOutlet weak var finishButton: UIButton!
    
    // prepare segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
            if segue.identifier == resultScreenIdentifier{
            let vc = segue.destination as! ResultViewController
            vc.data = sender as! String
            
        }
    }
    
    let resultScreenIdentifier = "resultScreenSegue"
    
    func moveToResultView(){
         performSegue(withIdentifier: resultScreenIdentifier, sender: score)
    }
    
    @IBAction func finishButtonClicked(_ sender: UIButton) {
        
        //perform segue
        let score = "\(calculateScore())"
        moveToResultView()
        
    }
    // calculate the score of quiz using loop
    func calculateScore()->Int{
        var numOfCorrectAnswers = 0
        for question in allQuestions.list{
            if question.isAnswerCorrect {
                numOfCorrectAnswers = numOfCorrectAnswers + 1
                //print(numOfCorrectAnswers)
            }
        }
        return numOfCorrectAnswers
    }
    func nextQuestion(){
        showResultView(isCorrect: (question?.isAnswerCorrect)!)
        questionCounter = questionCounter + 1
        question = fetchQuestion()
        setQuizView(question: question!)
        
        
    }
    
    func fetchQuestion() ->  Question{
       return  allQuestions.list[questionCounter]
    }
    

    func fetchCheckBoxList() -> [CheckBox]{
        let arr : [CheckBox] = [checkBox1,checkBox2,checkBox3,checkBox4]
        return arr
    }

}

推荐答案

Timer 不是特别准确.它们可能会受到严重抖动的影响.

Timers are not particularly accurate. They can suffer from significant jitter.

更好的方法是创建一个表示过期时间的Date(即Date(timeIntervalSinceNow:10),然后运行一个Timer间隔更短(我建议大约 0.1 秒).然后您可以根据目标 Date 计算剩余时间,并检查目标日期是否在过去.

A better approach is to create a Date that represents the expiration time (ie Date(timeIntervalSinceNow:10) and then run a Timer with a much shorter interval (I would suggest around 0.1 second). You can then calculate the time remaining based on the target Date and check if the target date is in the past.

这篇关于Swift NSTiimer 不遵循指定的间隔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆