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