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

有些话、适合烂在心里 提交于 2019-12-18 07:12:19

问题


I have a parent UIViewController and it has two different view containers - each of them has embedded UIViewController inside. It looks somehow like this:

I want to change the label on the right container when user presses the button stored on the left one.

So far I was able to do it while having a button placed in a parent view controller, then I was just using a protocol:

  • in my parent component I had:

    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
             } 
    
    
         }
    
  • in my container-embedded UIViewController I had:

    protocol HandleEmbedded: class {
        func setName(label: String)
    }
    
    class EmbeddedContainer: UITableViewController, HandleYourChat{
    
        func setName(label: String){
            print("setting label to \(label)")
        }
    }
    

Situation above works when I have the button placed in a parent controller and want to change the label inside a container. But what happens and how should I pass the data when the button is also embedded, but in a different container than the label? Do I have to pass the data through the parent controller? What's the best way for doing so?


回答1:


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.


来源:https://stackoverflow.com/questions/36530453/how-can-i-pass-data-from-one-container-to-another-both-embedded-in-the-same-uiv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!