如何将数据从第三个视图控制器传递回第一个视图控制器?

Posted

技术标签:

【中文标题】如何将数据从第三个视图控制器传递回第一个视图控制器?【英文标题】:How Do I Pass Data from Third View Controller Back to First View Controller? 【发布时间】:2014-12-12 01:24:56 【问题描述】:

我目前有一个导航控制器,其中包含一个视图控制器和两个表视图控制器。当用户导航到第二个表格视图控制器时,他们可以按下“+”栏按钮项,该按钮项以模态方式呈现另一个表格视图,其中包含一个包含文本字段的静态单元格。用户可以输入文本并按“完成”保存。当我的委托方法被调用时,视图控制器被关闭,用户输入的字符串被附加到第二个视图控制器的数组中。然后,表格视图在表格单元格中显示用户输入的文本。该数组已通过prepareForSegue 方法向上传递到堆栈。这目前正在工作,因为我可以在表视图中看到在第一个视图控制器中实例化数组的字符串。

当用户向下导航到第二个表视图之前的任何视图控制器时,会出现我的问题,其中包含用户输入的字符串,显示在单元格中。显然,我已经成功地将数据传递给以前的视图控制器,但是经过大量研究和测试,我无法成功地使用户输入的字符串保持不变。当我导航到以前的视图控制器然后返回到第二个表视图时,用户输入的数据消失了,数组只包含初始数据。

我知道 Swift 中的数组是结构体,并且在向上传递堆栈时会复制这些值。当我导航到前一个视图控制器时,为什么用户输入的数据会消失,这是有道理的。之前的视图控制器实际上并不包含用户输入的数据。这是否意味着我需要将字符串附加到初始视图控制器中的数组而不是第二个表视图控制器中的数组?如果是这种情况,我不确定如何从第三个视图控制器访问初始视图控制器。

我访问过的所有文档和教程都是基于将数据从当前视图控制器传递回前一个视图控制器,这是一个委托,然后关闭接受输入的视图控制器。

如何将用户输入的字符串从最后一个视图控制器传递回初始视图控制器?

【问题讨论】:

视图控制器不应该知道父视图控制器存在。父母可以与孩子交谈,但孩子绝不能与父母交谈。如果孩子改变了一些东西,它会发送一个通知,而父母会从那里接受它。 【参考方案1】:

实际上,Objective C 中有很多消息传递机制,除了 Phillip 的回答,我建议您使用NSNotificationCenter,通过它您可以发布通知并在需要时捕获它们。发布的通知可以包含自定义对象、字符串和名称,您应该为其添加观察者以便接收该通知。

注册特定通知:

[[NSNotificationCenter defaultCenter] addObserver:object_to_handle_notification selector:@selector(notificationReceived:) name:@"my_notification" object:nil];

发布通知:

[[NSNotificationCenter defaultCenter] postNotificationName:@"my_notification" object:userEnteredString];

处理通知:

- (void)notificationReceived:(NSNotification *)notification

    NSString *userEnteredString = notification.object;
    //do whatever you want with the user entered string

此外,您应该在完成后移除通知的观察者。 希望这会有所帮助。祝你好运!

【讨论】:

【参考方案2】:

创建一个负责维护数据模型的类。您可以将其设为单例,也可以通过应用程序委托(或其他选项)获得该类的对象。当控制器希望应用程序的其他部分可以使用信息时,它会将其发送到数据模型进行更新。当控制器想要显示信息时,它会从数据模型中获取信息。

控制器之间不再有数据依赖关系,必须弄清楚要交换什么。

【讨论】:

【参考方案3】:

您可以做的是将 firstViewController 作为参数从 SecondViewController 的 prepareForSegue 方法中传递给 ThirdViewController。

FirstViewController:

class FirstViewController: UIViewController 
  var a:String!

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
      var destination=segue.destinationViewController as? SecondViewController
      destination?.firstViewCont=self
    

第二视图控制器:

class SecondViewController: UIViewController 
  var firstViewCont:FirstViewController!

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
      var destination=segue.destinationViewController as? ThirdViewController
      destination?.FViewCont=self.firstViewCont
    

第三视图控制器:

class ThirdViewController: UIViewController 
  var FViewCont:FirstViewController!

  @IBAction func textFieldEdited(sender: UITextField) 
         FViewCont.a!=sender.text
  

这是最不切实际的方法之一。我建议你了解Navigation View Controllers。在做这样的事情时,它们就像一种魅力。

【讨论】:

以上是关于如何将数据从第三个视图控制器传递回第一个视图控制器?的主要内容,如果未能解决你的问题,请参考以下文章

将数据从一个选项卡控制器快速传递到另一个选项卡控制器

向前传递后如何将数据向后传递给视图控制器?

如何将字符串从根视图控制器传递到另一个视图?

如何在 Swift 中的视图之间传递数据

swift 4 中使用 performSegue 打开的关闭页面时,如何在视图控制器和 TableViewController 之间传递数据?

在第三个和第一个视图控制器之间传递数据