iOS 与集合控制器的 Child 个控制器之间的通信

iOS communication between to Child Controllers of Collection Controller

我目前正在为 iOS 开发一个用 Swift 编写的应用程序,并且到目前为止构建了一个带有 UIPageViewController 和两个 child 视图控制器的界面。

一切正常,但有时我会触发 PageViewController 来设置不同的视图控制器。发生这种情况时,我想将数据从一个 child 传递到另一个。

现在我知道问得最多的 iOS 开发问题之一是如何在两个 UIViewControllers 之间传递数据,但我的情况非常具体,我找不到类似的问题。如果我错了,我将不胜感激。此外,我不只是在寻找解决方案,因为我自己找到了一个。我正在寻找最好的,我知道这很难判断,但至少我正在寻找比我的更好的。

所以我想了个出路,但我觉得不是很优雅。所以我通过代表交换数据。基本上,我通过 Delegation.

从 Child View Controller A 到 PageViewController 再到 Child View Controller B

一切正常,但我不知道这是否是最好的方法,或者是否还有其他更好的方法。

非常感谢您的帮助。

Q

有多种沟通模式,没有最佳方法,这取决于您要做什么,或者您如何实施它。

从所有角度来看,您所做的可能是最好的方法,但使用的代码量很大。由于您的父级(页面视图控制器)负责所有工作,因此最好也传送它需要的所有数据。目前在 2 个视图控制器之间,以后可能在 3 个之间。您也可以简单地更改这些视图控制器,但保留用于检索数据的协议。

但是这里有一个很大的问题。如果视图控制器的数量会增加,那么您可能会发现自己遇到了以前的视图控制器正在被释放的问题(如果这还没有发生)所以最后视图控制器 D 无法访问视图控制器 A 只是因为 A 不再存在。

这些事情的解决方案实际上取决于什么,但根据你的问题,我可以假设你正在将一些数据从一个视图控制器传递到另一个视图控制器,比如通过多个屏幕收集用户数据的入职。在这种情况下,最好有一个包含所有需要的数据的 class,例如:

class MyData {
    var dataA: DataA?
    var dataB: DataB?
    var dataC: DataC?
}

现在页面控制器负责创建此类数据并将它们传递给将 use/modify 数据的每个视图控制器。所以在页面视图控制器中:

var myData: MyData = MyData()

func prepareViewControllerA() {
    let controller: ViewControllerA...
    controller.myData = myData
    ...
}

现在每个视图控制器都有自己的 属性 来访问同一个数据对象并对其进行修改。您还可以向 class 添加委托,以便页面控制器可以监听其事件:

protocol MyDataDelegate: class {
    func myData(_ sender: MyData, updatedA: DataA?)
    func myData(_ sender: MyData, updatedB: DataB?)
    func myData(_ sender: MyData, updatedC: DataC?)
    func myDataAreFinalized(_ sender: MyData)
}

class MyData {
    var dataA: DataA? {
        didSet {
            delegate?.myData(self, updatedA: dataA)
        }
    }
    var dataB: DataB? {
        didSet {
            delegate?.myData(self, updatedB: dataB)
        }
    }
    var dataC: DataC? {
        didSet {
            delegate?.myData(self, updatedC: dataC)
        }
    }

    weak var delegate: MyDataDelegate?

    func finalize() {
        delegate?.myDataAreFinalized(self)
    }

}

现在您的页面控制器可以使用它了:

var myData: MyData = {
    let data = MyData()
    data.delegate = self
    return data
}()

和代表们:

func myData(_ sender: MyData, updatedA: DataA?) {
}
func myData(_ sender: MyData, updatedB: DataB?) {
}
func myData(_ sender: MyData, updatedC: DataC?) {
}
func myDataAreFinalized(_ sender: MyData) {
    dismiss(animated: true, completion: nil)
}