如何让我的倒数计时器在每次加载视图时重置?
How to get my countdown timer to reset to every time the view loads?
在我的 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()
}
}
您的代码存在问题 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),然后当视图出现时,你会创建一个新的计时器。
您可以在您的第一个视图控制器上实现函数 viewDidAppear(),当您的第二个 viewcontroller 被关闭时将自动调用此函数,因此将(再次)看到第一个。
所以在你的第一个视图控制器中创建这个函数:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// HERE PUT YOUR TIMER RESET
// ...
}
在我的 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()
}
}
您的代码存在问题 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),然后当视图出现时,你会创建一个新的计时器。
您可以在您的第一个视图控制器上实现函数 viewDidAppear(),当您的第二个 viewcontroller 被关闭时将自动调用此函数,因此将(再次)看到第一个。
所以在你的第一个视图控制器中创建这个函数:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// HERE PUT YOUR TIMER RESET
// ...
}