2017-07-25 54 views
1

我正在开发一个测验应用程序,还有第二个视图控制器出现在初始视图控制器后面,您需要回答一个问题。在第二个视图控制器上,用户必须按下按钮才能返回到初始视图控制器,以询问另一个问题。但是,当我从第二个视图控制器回来时,我认为正在创建初始视图控制器的新实例,并向用户询问他们已经回答的问题。 swift文件中用于初始视图控制器的代码是这样构造的,即一旦用户被问到一个问题,那么该问题就会被索引从数组中移除。我怎样才能使它从第二个视图控制器继续创建初始视图控制器的新实例?或者有没有办法第二个视图控制器可以访问与初始视图控制器相同的方法?如何在传递前向后传递数据到视图控制器?

这里是我的初始视图控制器代码:

import UIKit 

class ViewController: UIViewController { 


var questionList = [String]() 


func updateCounter() { 

    counter -= 1 
    questionTimer.text = String(counter) 

    if counter == 0 { 


     timer.invalidate() 
     wrongSeg() 
     counter = 15 

    } 



} 


func randomQuestion() { 



    //random question 
    if questionList.isEmpty { 
     questionList = Array(QADictionary.keys) 

     questionTimer.text = String(counter) 




    } 






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

     } 
    } 


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 { 

     counter = 15 
     questionTimer.text = String(counter) 
    } 
else if (sender.tag != Int(rightAnswerBox)) { 

    wrongSeg() 
print ("Wrong!") 
    timer.invalidate() 
    questionList = [] 

    } 

    randomQuestion() 

} 

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 




class ContinueScreen: UIViewController { 




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

回答

1

你需要什么,先生是代表或开卷SEGUE。我更喜欢代表,因为他们更容易理解,我认为更强大一点。

在你ContinueScreen视图控制器定义一个类似的协议:

protocol QuizCompletedDelegate { 
    func completedQuiz() 
    func canceledQuiz() 
} 
在ContinueScreen视图控制器

还需要声明类型的可选代表QuizCompletedDelegate

var delegate: QuizCompletedDelegate? 

...和使用该代表在适当时调用功能:

@IBAction func didPressContinue(_ sender: Any) { 
    if allQuestionsAnswered == true { 
     delegate.completedQuiz() 
    } else { 
     delegate.cancelledQuiz() 
    } 
} 

在您的初始视图控制器是您实现该协议的功能:

extension ViewController: QuizCompletedDelegate { 
    func completedQuiz() { 
     //Handle quiz complete 
    } 
    func cancelledQuiz() { 
     //Handle quiz cancelled 
    } 
} 

然后,你需要做的最后一件事是设置你的ContinueScreen视图控制器的代表在初始视图控制器的prepareForSegue功能。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "showContinueScreen" { 
     let continueVC = segue.destination as! ContinueScreen 
     continueVC.delegate = self 
    } 
} 

您的初始视图控制器的ViewDidAppear删除调用randomQuestion(),和你在企业里!

+0

你从哪里得到所有的问题在if语句中回答? –

+0

这只是您的逻辑的占位符,以确定是否所有问题都得到了答案。这不是复制和粘贴代码,你需要适应它,以适应你正在尝试做的事情。这就是你如何使用委托模式来完成你想要的。 – Zig

+0

感谢您的洞察,我很感激! –

0

当你回去时,它不应该创建一个新的视图控制器。如果确实如此 - 这很糟糕 - 您应该重新构建应用程序的流程......要向前传递数据,我们应该使用依赖注入。将数据传递给前一个视图控制器 - 使用iOS委托模式。我建议花费30-40分钟阅读(并理解本文),这将使你在未来更加清晰:http://matteomanferdini.com/how-ios-view-controllers-communicate-with-each-other/

相关问题