Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在尚未加载的VC上使用委托_Ios_Swift_Delegates - Fatal编程技术网

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

Ios 在尚未加载的VC上使用委托,ios,swift,delegates,Ios,Swift,Delegates,我试图做一些我认为很简单的事情,但我一直在努力。我已经做了很多搜索,但我找不到任何我想要尝试做的事情 我试图将字符串从一个VC传递到下一个VC,并使用委托更改其上的标签。我遇到的问题是,由于某种原因,代理显示为零。我收到此错误:线程1:致命错误:在展开可选值时意外发现nil以下是我的代码的一些图像,以帮助您理解我所写的内容 第一个VC代码: @IBAction func nextBtn(_ sender: Any) { let newWorkoutVC = storyboard?

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

我试图将字符串从一个VC传递到下一个VC,并使用委托更改其上的标签。我遇到的问题是,由于某种原因,代理显示为零。我收到此错误:线程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
}

若要将数据传递给要显示的视图控制器,不需要使用委托。当您希望将数据从VC a传递到呈现a的VC时,通常使用委托

在这里,您可以直接设置属性,因为您已经获得了实例newWorkoutVC:

其中,在NewWorkoutVC中定义了workoutName,如下所示:

var workoutName: String!
override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated: animated)
    workoutNameLabel.text = workoutName
}

协议/委托模式向后

如果第一个VC将实例化第二个VC,并将其表示为NewWorkUtVC,则无需委托即可将数据从第一个VC移动到第二个VC。在你说的那一刻

let newWorkoutVC = storyboard?.instantiateViewController(
                       withIdentifier: "NewWorkoutVC") as! NewWorkoutVC
。。。第一个VC有一个对第二个VC的引用,可以在显示它之前设置它的任何属性值

但是,第一个VC不得试图触摸第二个VC的任何界面。相反,它应该设置一个简单的属性值,让第二个VC获取该属性值并处理自己的接口,通常在自己的viewDidLoad中

那么委托/协议模式是什么呢?如果第二个VC以后需要将信息传递回第一个VC!为了实现这一点,第一个VC还将,在我刚才谈论的时候,将第二个VC的委托属性设置为self,即第一个VC,这样第二个VC将知道如何调用第一个VC。在委托协议模式中:

委托属性在第二个VC中声明,并由第一个VC设置为对self的引用,是第二个VC如何知道其委托人的

协议由第二个VC定义并由第一个VC采用,是第二个VC如何知道它可以对其代表说什么

extension NewWorkoutVC: WorkoutNameDelegate{

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

关于双向交流的教学示例,请看这个可下载项目中的ViewController和SecondViewController:还有很多其他内容,示例非常紧凑,但其中之一是使用委托/协议模式与呈现视图控制器进行前向通信,然后再与呈现视图控制器进行后向通信。