通过后退按钮将变量传递给其他视图控制器

Posted

技术标签:

【中文标题】通过后退按钮将变量传递给其他视图控制器【英文标题】:Pass variable to other view controller via back button 【发布时间】:2019-03-05 13:17:29 【问题描述】:

我有两个视图控制器。一个是通过“显示”转场导航到的。 UINavigationBar 中有一个后退按钮,我没有更改。后退按钮返回到初始视图控制器。在带有后退按钮的视图控制器中,我将数据存储在一个变量中。

如何将这些数据传递给我的初始视图控制器?

我试过了:

viewWillDisappear(_ animated: Bool) 
    let vc = ViewController()
    vc.data = items

但打印时初始视图控制器中的数据为空。

我尝试过使用:

prepare(for segue: ...)

但我不确定后退按钮使用什么 segue。

我似乎也无法将后退按钮的操作添加到我的视图控制器。

【问题讨论】:

Let vc = ViewController() 那是在创建一个全新的对象,而不是你想的那个。 Pass data back to previous viewcontroller的可能重复 【参考方案1】:

vc 与您要返回的控制器不是同一个控制器。


在第二个控制器中创建闭包变量,并将模型数组作为参数

class SecondViewController: UIViewController 
    var callback: (([Item]) -> Void)?

然后在第一个控制器的prepare(for:sender:) 中分配目标的callback 并声明您要在调用callback 时更改第一个控制器的data

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == "yourSegueIdentifier" 
        let destinationVC = segue.destination as! SecondViewController
        destinationVC.callback =  items in
            self.data = items
        
    

然后,当您需要(在第二个控制器的 viewWillDisappear 中)使用给定项目调用 callback

override func viewWillDisappear(_ animated: Bool) 
    callback?(items)

【讨论】:

可能是回调中的[weak self] prepare() 给我一个错误。不能调用非函数类型的值'(([Item]) -> Void)?' @Nathaniel 我的错误,检查编辑。我忘了分配符号【参考方案2】:

您可以使用委托。首先,创建一个协议:

protocol getItemsDelegate 
    func getItems(_ items: [String])

在您的第一个视图控制器的类定义中添加 getItemsDelegate:

class myFirstViewController: UIViewController,getItemsDelegate

将此添加到您的第一个视图控制器中的 prepare 方法中:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    let vc = segue.destination as! mySecondViewController
    vc.delegate = self

最后,在您的第一个视图控制器中,添加以下内容:

func getItems(_ items: [String]) 
    // Do something with items

在您的第二个视图控制器中,声明以下属性:

var delegate: getItemsDelegate?

然后:

override func viewWillDisappear(_ animated: Bool) 
   delegate?.getItems(items)

这只是另一种方式。

【讨论】:

使用 viewWillDisappear 传回数据是很常见的错误。问题是每次用户开始向后滑动时都会调用 viewWillDisappear,如果用户在中途停止,您将停留在同一个 viewController 但委托方法将被激活,这可能会导致错误。 从未想过用户停止滑动的可能性。但是,在这种情况下,我相信有一个不需要滑动的后退按钮。但请牢记这个潜在的错误! 在导航控制器中,默认启用向后滑动,作为良好 UX 的一部分,不建议禁用它。所以是的,记住这个潜在的错误非常重要。

以上是关于通过后退按钮将变量传递给其他视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

后退按钮始终命名为前一个视图控制器

在 Swift 中缺少带有导航控制器的视图控制器中的后退按钮

如何通过控制器将两个不同模型的值作为 Laravel 8 中的单个返回变量传递给视图文件

将按钮值从视图传递给控制器​​(codeigniter)

从按钮将值传递给视图控制器字典

iOS 7 - 后退按钮后标签栏消失