如何将数据从一个容器传递到另一个容器,两者都嵌入在 swift 中的同一个 uiviewcontroller 中?

how can I pass data from one container to another, both embedded in the same uiviewcontroller in swift?

我有一个父级 UIViewController,它有两个不同的视图容器 - 每个都嵌入了 UIViewController。它看起来像这样:

我想在用户按下存储在左侧容器上的按钮时更改右侧容器上的标签。

到目前为止,我能够在父视图控制器中放置一个按钮时做到这一点,然后我只是使用了一个协议:

当我将按钮放置在父控制器中并想要更改容器内的标签时,上述情况有效。但是当按钮也被嵌入但与标签位于不同的容器中时,会发生什么?我应该如何传递数据? 我必须通过父控制器传递数据吗?最好的方法是什么?

要将数据从一个嵌入式 ViewController 传递到另一个嵌入式 ViewController,请让父级处理传输。在这里,我提供了一个完整的示例,其中包含三个 ViewController 和一个 StringTaker 协议。主要 ViewControllerLabelViewController 都实现了这个协议。主 ViewControllerButtonViewController 中获取一个字符串并将其传递给嵌入的 LabelViewController.

ViewController.swift

import UIKit

protocol StringTaker: class {
    func takeString(string: String)
}

class ViewController: UIViewController, StringTaker {

    weak var stringTaker: StringTaker?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "EmbedButtonViewController" {
            let dvc = segue.destinationViewController as! ButtonViewController
            dvc.delegate = self
        } else if segue.identifier == "EmbedLabelViewController" {
            let dvc = segue.destinationViewController as! LabelViewController
            stringTaker = dvc
        }
    }

    // Receive the string from the ButtonViewController
    func takeString(string: String) {
        // Pass it to the LabelViewController
        stringTaker?.takeString(string)
    }
}

按钮ViewController.swift

import UIKit

class ButtonViewController: UIViewController {

    weak var delegate: StringTaker?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func generateString(sender: UIButton) {
        let cities = ["Boston", "Paris", "Sydney", "Mumbai", "Lima"]

        // Pick a random city
        let city = cities[Int(arc4random_uniform(UInt32(cities.count)))]

        // Pass the string to the delegate
        delegate?.takeString(city)
    }
}

标签ViewController.swift

import UIKit

class LabelViewController: UIViewController, StringTaker {

    @IBOutlet weak var myLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func takeString(string: String) {
        myLabel.text = string
    }
}

注意事项:

  1. LabelViewControllerButtonViewController 对使用它们的 ViewController 一无所知。这使得重用它们变得更加容易。您可以将它们嵌入到另一个 viewController 中,只要您正确实施 StringTaker 协议并设置 delegate,一切正常。
  2. 将其连接起来的关键是命名嵌入转场,然后在 prepareForSegue 中正确设置委托。一旦将 Container 添加到 ViewController.
  3. 中,就可以在 Document Outline 视图中找到 segues