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

烂漫一生 提交于 2019-12-01 13:24:47

To pass data from one embedded ViewController to another embedded ViewController, have the parent handle the transfer. Here I have provided a complete example with three ViewControllers and a single StringTaker protocol. Both the main ViewController and the LabelViewController implement this protocol. The main ViewController takes a string from the ButtonViewController and passes it on to the embedded 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
    }
}

Things to note:

  1. The LabelViewController and the ButtonViewController know nothing about the ViewController that uses them. This makes it easier to reuse them. You could embed them in another viewController and as long as you properly implement the StringTaker protocol and set up the delegate, everything works.
  2. The key to hooking this up in in naming the embed segues and then properly setting up the delegates in prepareForSegue. The segues can be found in the Document Outline view once the Container is added to the ViewController.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!