【问题标题】:iOS communication between to Child Controllers of Collection Controller集合控制器与子控制器之间的 iOS 通信
【发布时间】:2018-09-05 15:03:23
【问题描述】:

我目前正在开发一个用 Swift 编写的 iOS 应用程序,并构建了一个包含 UIPageViewController 和两个子视图控制器的界面。

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

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

所以我想了一个办法,但我觉得不是很优雅。所以我通过代表交换数据。基本上,我通过Delegation 将它从子视图控制器A 引导到PageViewController 到子视图控制器B。

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

非常感谢您的帮助。

【问题讨论】:

    标签: ios swift delegation


    【解决方案1】:

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

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

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

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

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

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

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

    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)
    }
    

    【讨论】:

    • 非常感谢您的回答很有帮助
    【解决方案2】:

    有几种沟通模式,没有最好的方法,这取决于你要做什么,或者你如何实现它。

    I suggest reading to this answer.

    【讨论】:

    • 感谢您的回答,但我真正不喜欢的是我必须从子视图 A 到页面视图,然后再到子视图 B,这一次没关系,但它会使代码变得复杂或者至少在添加更多内容时不会那么快阅读
    猜你喜欢
    • 2012-08-10
    • 1970-01-01
    • 2012-04-27
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多