Ios Swift NSTiimer未遵循指定的间隔

Ios Swift NSTiimer未遵循指定的间隔,ios,swift,iphone,nstimer,Ios,Swift,Iphone,Nstimer,我正在尝试创建一个测验应用程序,当计时器过期时(即10秒,我希望计时器的间隔为1秒),每个问题都有一个计时器。它会自行重置,然后取回下一个问题,计时器从10秒开始重新启动。。。但我的问题是,当第一个问题加载时,计时器没有遵循固定的时间间隔,它显示的时间间隔为2。。。i、 e.10,8,6。。然后对于第二个问题,它每隔3秒跳一次,同样地,间隔也会增加 导入UIKit class ViewController: UIViewController { let allQuestions = Q

我正在尝试创建一个测验应用程序,当计时器过期时(即10秒,我希望计时器的间隔为1秒),每个问题都有一个计时器。它会自行重置,然后取回下一个问题,计时器从10秒开始重新启动。。。但我的问题是,当第一个问题加载时,计时器没有遵循固定的时间间隔,它显示的时间间隔为2。。。i、 e.10,8,6。。然后对于第二个问题,它每隔3秒跳一次,同样地,间隔也会增加

导入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
    }

}
类ViewController:UIViewController{
让所有问题=问题bundle()
var pickedAnswer:Int=0
var问题计数器=0
变量分数:Int=0
变量定时器:定时器!
@IBVAR问题标签:UILabel!
@IBVAR弱倒计时标签:UILabel!
@IBL弱var ansLbl1:UILabel!
@IBL弱var ansLbl2:UILabel!
@IBVAR ansLbl3:UILabel!
@IBVAR ansLbl4:UILabel!
@IBOUTLE弱var复选框1:复选框!
@IBOUTLE弱var复选框2:复选框!
@IBOUTLE弱var复选框3:复选框!
@IBOUTLE弱var复选框4:复选框!
var复选框列表:[复选框]=[]
@iAction func correct\u Answer\u Checbox\u Btn(\u发送方:AnyObject){
//打印(\(sender.tag)\(字符串(描述:问题?.correctAnswer)))
UpdateCheckBox(发件人:发件人)
如果sender.tag==问题?。请更正答案{
问题?.isAnswerCorrect=正确
问题?.selectedAnswer=sender.tag
//分数=分数+1
}
否则{
问题?.isAnswerCorrect=false
}
}
func updatecheckbox(发送方:AnyObject){
对于checkBoxlist中的checkBoxItem{
如果checkBoxItem.tag!=sender.tag{
checkBoxItem.isChecked=false
}
}
}
@IBVAR下一个按钮:UIButton!
@iAction func nextbtn已单击(u发件人:AnyObject){
做{
试试handleNextQuestion()
}
抓住{
moveToResultView()
}
}
func handleNextQuestion()抛出{
下一个问题()
如果questionCounter==allQuestions.list.count-1{
finishButton.ishiden=false
nextButton.ishiden=true
//scoreLbl.text=“\(分数)”
}
}
问:问题?
var countTime=10.0
重写func viewDidLoad(){
super.viewDidLoad()
finishButton?.isHidden=true
checkBoxlist=fetchCheckBoxList()
question=fetchQuestion()
setQuizView(问题:问题!)
//加载视图后,通常从nib执行任何其他设置。
}
//在函数中设置所有问题
@objc func更新(){
如果(计数时间>0){
countTime=countTime-1
self.countdownlab.text=字符串(countTime)
}否则{
timer.invalidate()
countTime=10.0
做{
试试handleNextQuestion()
}
抓住{
moveToResultView()
}
}
}
func startTimer(){
timer=timer.scheduledTimer(时间间隔:1.0,目标:self,选择器:#选择器(ViewController.update),userInfo:nil,repeats:true)
}
func setQuizView(问题:问题){
self.countdownlab.text=“10”
startTimer()
questionLabel.text=question.questionText
ansLbl1.text=question.answer1
ansLbl2.text=question.answer2
ansLbl3.text=question.answer3
ansLbl4.text=question.answer4
如果question.selectedAnswer==Constants.DEFAULT\u回答{
对于checkBoxlist中的checkBoxItem{
checkBoxItem.isChecked=false
}
}
}
@IBVAR完成按钮:UIButton!
//准备赛格
覆盖功能准备(对于segue:UIStoryboardSegue,发送方:有吗?){
如果segue.identifier==resultScreenIdentifier{
设vc=segue.destination为!ResultViewController
vc.data=发送方为!字符串
}
}
让resultScreenIdentifier=“resultScreenSegue”
func moveToResultView(){
PerformScheue(带标识符:resultScreenIdentifier,发件人:分数)
}
@iAction func finishButtonClicked(\发送方:UIButton){
//表演序曲
let score=“\(calculateScore())”
moveToResultView()
}
//使用循环计算测验分数
func calculateScore()->Int{
var numOfCorrectAnswers=0
对于allQuestions.list中的问题{
如果问题是正确的{
numOfCorrectAnswers=numOfCorrectAnswers+1
//打印(数字)
}
}
返回正确答案
}
func nextQuestion(){
showResultView(是否正确:(问题?.isAnswerCorrect)!)
问讯台=问讯台+1
question=fetchQuestion()
setQuizView(问题:问题!)
}
func fetchQuestion()->问题{
返回所有问题。列表[问题计数器]
}
func fetchCheckBoxList()->[复选框]{
让arr:[复选框]=[复选框1、复选框2、复选框3、复选框4]
返回arr
}
}

计时器
不是特别精确。它们可能会出现明显的抖动

更好的方法是创建一个表示过期时间的
Date
(即
Date(timeIntervalSinceNow:10)
,然后以更短的时间间隔运行
计时器(我建议