【问题标题】:Share Data Between View Controller and Container View在视图控制器和容器视图之间共享数据
【发布时间】:2017-06-06 05:57:13
【问题描述】:

我有一个视图控制器,它与第二个视图控制器有一个转场,我将一些数据传递给第二个以准备转场。 问题是:第二个视图控制器有一个容器视图,我需要与之共享该数据。我尝试使用 prepare for segue 但在这种情况下不起作用。

更新:

查看控制器代码:

class ViewController: UITableViewController, ContainerViewDelegate {

   var myContainerView = ContainerView()
   var id: String!

   override func viewDidLoad() {
        super.viewDidLoad()
        id = "123"
        myContainerView.delegate = self
   }

   func initialize() -> String {
        return id
   }
}

容器视图代码:

protocol ContainerViewDelegate {
   func initialize() -> String
}

class ContainerView: UICollectionViewController {

   var delegate: ContainerViewDelegate!
   var id: String!
   override func viewDidLoad() {
       super.viewDidLoad()
       id = delegate.initialize()
       print(id)
   }
}

我收到错误:fatal error: unexpectedly found nil while unwrapping an Optional value 在线:id = delegate.initialize()

【问题讨论】:

  • 使用Delegate 模式。谷歌一下。
  • 我什至不知道什么是“容器视图”。
  • @shallowThought 谢谢。我确实尝试过使用 Delegate,但我得到了一些 nil 异常,我认为我没有以正确的方式使用它。能否请您提供如何使用 Delegate 的步骤的结构?
  • @nouf 请发布您尝试过的内容以及遇到“一些零异常”的位置,以便我们帮助您查明问题。
  • @ElTomato 'container view' 是您在 Xcode Storyboard 中用来挂钩子视图控制器的视图

标签: swift uicontainerview


【解决方案1】:

您在设置代理的正确轨道上。

在故事板中:

  • 从ContainerView 创建一个Embed Segue 类型的Segue 到要嵌入的ViewController。
  • 选择segue并设置Identifier。

在代码中,在prepareForSegue():

  • 设置myContainerView 属性
  • 设置委托

    class ViewController: UITableViewController, ContainerViewDelegate {
        var myContainerView:ContainerView? // we do initialize it in prepareForSegue()
        var id: String!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            id = "123"
            // myContainerView.delegate = self //myContainerView is nil here. We set it in prepareForSegue
        }
    
        func initialize() -> String {
            return id
        }
    
        let embedSegueID = "the identifier you set to your embed segue in Storyboard"
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if (segue.identifier == embedSegueID) {
                let dvc = segue.destination as! ContainerView
                // Now you have a pointer to EmbeddedViewController.
                // You can save the reference to it, or pass data to it.
                myContainerView = dvc
                myContainerView.delegate = self
            }
            print(segue.identifier)
        }
    }
    

如果您想将数据从您的 ViewController 传递到嵌入在您的 destinationViewController 中的 AnotherViewController(我如何理解您的问题),我会:

  • 如上例所示将其传递给destinationViewController (prepareForSegue)
  • 而不是将其从destinationViewController 中传递给viewWillAppear() 中的AnotherViewController。

在这种情况下,我如何理解您的用例,您不需要委托并且可以删除所有委托相关代码(initialize、ContainerViewDelegate 协议、属性 var delegate: ContainerViewDelegate! 以及对它的所有调用。

【讨论】:

  • 这是一个很好的解决方案。谢谢
  • 欢迎您!我在答案的末尾又添加了一个想法。
【解决方案2】:

两种方式:

  1. 在您的第二个视图控制器中,覆盖 prepare(for:sender:)

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
        if segue.identifier == "loadContainerView" { // replace with your segue identifier
             let childViewControllerController = segue.destination
             // pass data
        }
    }
    
  2. 在您的第二个视图控制器中,使用 childViewControllers 访问您的容器视图的控制器。

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if let childViewController = childViewControllers.first {
            // pass your data
        }
    }
    

示例项目: https://www.dropbox.com/s/he97ldzhav2non3/ContainerViewTest.zip?dl=0

【讨论】:

    【解决方案3】:

    您可以使用 prepare for segue 并将您想要的所有内容发送到第二个 Controller ...

        override func prepareForSegue(segue: UIStoryboardSegue, sender:   AnyObject?) {
        // get a reference to the second view controller
        let secondViewController = segue.destinationViewController as! SecondViewController
    
        // set a variable in the second view controller to pass
        secondViewController.data = data
        }
    

    【讨论】:

    • 这在 ContainerView 是第二个视图容器的情况下不起作用。因为ContainerView的ViewDidLoad会在prepareForSegue之前调用
    • 第二个视图控制器调用viewDidAppear到容器时可以设置数据
    猜你喜欢
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 2014-04-25
    • 1970-01-01
    相关资源
    最近更新 更多