向前传递后如何将数据向后传递给视图控制器? [英] How to pass data backwards to a view controller after passing forward?

查看:85
本文介绍了向前传递后如何将数据向后传递给视图控制器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个测验应用程序,并且第二个视图控制器出现在初始视图控制器之后,要求您回答问题。在第二个视图控制器上,用户必须按一个按钮以返回到初始视图控制器,并被询问另一个问题。但是,当我从第二个视图控制器中搜索回来时,我相信正在创建初始视图控制器的新实例,并向用户询问他们已经回答的问题。 swift文件中用于我的初始视图控制器的代码是这样构造的:当用户被问到一个问题时,该问题就会通过其索引从数组中删除。如何通过与第二个视图控制器的隔离而无法创建初始视图控制器的新实例?还是第二种视图控制器可以访问与初始视图控制器相同的方法?

Im developing a quiz app and there is a second view controller that appears after the initial view controller where you are asked to answer a question. On the second view controller you the user must press a button to return to the initial view controller to be asked another question. However when I segue back from the second view controller I believe a new instance of the initial view controller is being created and the user is asked questions they have already answered. The code in the swift file for my initial view controller is constructed that when once a user is asked a question once that question is removed from an array by it's index. How could I make it to where a new instance of the initial view controller isn't created from segueing from the second view controller? Or is there a way the second view controller can access the same methods as the initial view controller?

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

Here is my code for the initial view controller:

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)


}

这是第二个视图控制器的代码:

Here's the code to the second view controller:

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


推荐答案

您所需要的,先生是委托人还是散客。我更喜欢代表,因为它们更易于理解,而且我认为更强大。

What you need, sir is a delegate or an unwind segue. I far prefer delegates because they're easier to understand and I think a bit more powerful.

在ContinueScreen视图控制器中定义类似于以下的协议:

In your ContinueScreen view controller define a protocol similar to this:

protocol QuizCompletedDelegate {
    func completedQuiz()
    func canceledQuiz()
}

此外,在您的ContinueScreen视图控制器中,您还需要声明一个QuizCompletedDelegate类型的可选委托

Also in your ContinueScreen view controller you need to declare an optional delegate of type QuizCompletedDelegate

var delegate: QuizCompletedDelegate?

...,并在适当的时候使用该委托来调用函数:

... and use that delegate to call the functions when appropriate:

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

在初始视图控制器中,您将实现协议的功能:

In your initial view controller is where you implement the functions for the protocol:

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

然后,您需要做的最后一件事是在初始的prepareForSegue函数中设置ContinueScreen视图控制器的委托。

Then the last thing you need to do is set the delegate of your ContinueScreen view controller in the prepareForSegue function of your initial view controller.

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

删除在初始视图控制器的ViewDidAppear上对randomQuestion()的调用,您就在做生意!

Remove the call to randomQuestion() on your initial view controller's ViewDidAppear, and you're in business!

这篇关于向前传递后如何将数据向后传递给视图控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆