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

时间:2016-04-10 13:35:47

标签: ios swift uiviewcontroller segue uicontainerview

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

enter image description here

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

到目前为止,我可以在父视图控制器中放置一个按钮时执行此操作,然后我只是使用协议:

  • 在我的父组件中我有:

    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)
    }
    
    class EmbeddedContainer: UITableViewController, HandleYourChat{
    
        func setName(label: String){
            print("setting label to \(label)")
        }
    }
    

当我将按钮放在父控制器中并想要更改容器内的标签时,上面的情况有效。但是当嵌入按钮时,我应该如何传递数据,但是在与标签不同的容器中? 我是否必须通过父控制器传递数据?这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

要将数据从一个嵌入的ViewController传递到另一个嵌入的ViewController,请让父处理传输。在这里,我提供了一个包含三个ViewControllers和一个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)
    }
}

<强> 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后,可以在文档大纲视图中找到segues。