2017-07-25 59 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/

相關問題