在尚未加载的VC上使用委托

时间:2018-12-19 02:54:08

标签: ios swift delegates

我正在尝试做一些我认为很简单的事情,但是我一直在努力。我已经做了很多搜索,但找不到的正是我想要尝试做的。

我试图将字符串从一个VC传递到下一个VC,并使用委托更改其上的标签。我遇到的问题是由于某种原因,该代表显示为nil。 (我收到此错误:线程1:致命错误:在展开一个可选值时意外发现nil )下面是我的代码的一些图片,以帮助您了解我写的内容

第一个VC代码:

    @IBAction func nextBtn(_ sender: Any) {
    let newWorkoutVC = storyboard?.instantiateViewController(withIdentifier: "NewWorkoutVC") as! NewWorkoutVC
    if workoutNameTextField.text != ""{
        let workoutName = workoutNameTextField.text!
        nameDelegate.transferText(name: workoutName) //error appears on this line
        present(newWorkoutVC, animated: true, completion: nil)
    } else {
    }
}

第二个VC具有要实例化的委托,因为该委托应该在VC即将加载时发生,因此将在视图中出现。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let workoutNameVC = storyboard?.instantiateViewController(withIdentifier: "WorkoutNameVC") as! WorkoutNameVC
    workoutNameVC.nameDelegate = self

这是我的扩展名,使第二个VC符合我的委托。

extension NewWorkoutVC: WorkoutNameDelegate{

func transferText(name: String!) {
    workoutNameLabel.text = name
}

2 个答案:

答案 0 :(得分:1)

您的协议/代理模式倒退了。

如果第一个VC将实例化并显示第二个VC(NewWorkoutVC),则无需“委托”即可将数据从第一个VC移动到第二个VC。此刻你说

let newWorkoutVC = storyboard?.instantiateViewController(
                       withIdentifier: "NewWorkoutVC") as! NewWorkoutVC

...第一个VC引用了第二个VC,并且可以在呈现它之前和之后随时设置其任何属性值。

(但是,第一个VC不得尝试触摸第二个VC的界面中的任何一个。相反,它应该设置一个简单的属性值,然后让第二个VC拾取该属性值并处理具有自己的界面,通常在自己的viewDidLoad中。)

那么委托/协议模式是做什么用的?如果第二个VC将以后需要将信息 back 传递给第一个VC!为了使之成为可能,在我刚刚谈论的那一刻,第一个VC还将 second VC的delegate属性设置为self(即, first VC),以便第二个VC知道如何回调第一个VC。在委托协议模式中:

  • 在第二个VC中声明并被第一个VC设置为对self的引用的 delegate属性,是第二个VC知道它的代表是。

  • 由第二个VC定义并由第一个VC采纳的协议是第二个VC知道向其委托人说的话 / p>

答案 1 :(得分:0)

要将数据传递到将要显示的视图控制器,请不要使用委托。当您要将数据从VC $strtime = $record['Date'].' '.$record['Timezone']' hours'; echo date('Y-m-d H:i:s', strtotime($strtime)); 传递到显示A的VC时,通常使用委托。

在这里,您可以直接设置属性,因为已经有了实例(A):

newWorkoutVC

let newWorkoutVC = storyboard?.instantiateViewController(withIdentifier: "NewWorkoutVC") as! NewWorkoutVC if workoutNameTextField.text != ""{ let workoutName = workoutNameTextField.text! newWorkoutVC.workoutName = workoutName present(newWorkoutVC, animated: true, completion: nil) } workoutName中的定义如下:

NewWorkoutVC