一尘不染

如何将数据从一个容器快速传递到另一个容器,而这两个容器都迅速地嵌入了同一个uiviewcontroller中?

swift

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

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

到目前为止,我已经能够在将按钮放在父视图
控制器中的同时做到这一点,然后我只使用了一种协议:

  • 在我的父组件中,我有:

    class ParentController: UIViewController {
    
    var delegateEmbedded:HandleEmbedded?
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "segueToFirstEmbeddedController"){
    
        if let embeddedView = segue.destinationViewController as? EmbeddedContainer {
    
           self.delegateEmbedded = embeddedView
         }
    
     }
    
  • 在我的容器嵌入式UIViewController中,我有:

        protocol HandleEmbedded: class {
        func setName(label: String)
    }

嵌入式容器类:UITableViewController,HandleYourChat {

        func setName(label: String){
            print("setting label to \(label)")
        }
    }

当我将按钮放在父控制器中并且
想要更改容器内的标签时,上述情况起作用。但是会发生什么,
当按钮也被嵌入但
与标签位于不同的容器中时,如何传递数据?我是否必须通过父控制器传递数据?
这样做的最佳方法是什么?


阅读 419

收藏
2020-07-07

共1个答案

一尘不染

要将数据从一个嵌入式ViewController传递到另一个嵌入式ViewController,请让父级处理传输。在这里,我提供了一个完整的示例,其中包含三个ViewController和一个StringTaker协议。主要ViewController和LabelViewController实现此协议。mainViewController从中获取一个字符串ButtonViewController,并将其传递给嵌入式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)
    }
}

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

LabelViewController.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. 命名嵌入segues然后在中正确设置代表的关键prepareForSegue。将容器添加到中后,可以在“ 文档大纲”视图中找到这些序列。ViewController
2020-07-07