简体   繁体   中英

How do I constantly send data from parent ViewController to ContainerViewController

In my app, the main ViewController is getting data from a sensor 60 times a second. In order to display the data, I have two ContainerViews, one that displays the raw data and another that displays it in a graph.

在此处输入图片说明

How do I either constantly send data from my mainVC to the ContainerView or let the ContiainerViews access variables in my mainVC?

There are lots of ways to slice this.

I would advise against collecting that data from your sensors in a view controller. That's not really a view controller's job. It gets worse when there are multiple objects who need that sensor data.

Probably the cleanest design would be to create a separate object (I'll call it a SensorManager) that collects your sensor data and passes it to anybody who cares.

You could have the SensorManager use the NotificationCenter to broadcast notifications, and then have all interested objects add observers for the notifications that they care about. That gives you very loose coupling between the SensorManager and the objects that get notified about sensor data. The downside is that the code is harder to debug.

Alternately, could set up your SensorManager to have an array of objects that it notifies. I would define a protocol that has one or more methods that get called with sensor data, and have the SensorManager maintain an array of client objects that conform to that protocol. When the SensorManager has new sensor data, it would loop through the array of client objects and call the appropriate method on each to tell each one about the new data. This second option is sort of like the delegate design pattern, but is a one-to-many, where the delegate pattern is a one-to-one passing of info.

If you are wedded to the idea of collecting the sensor data in your main view controller and you create your child view controllers using embed segues then you could write a prepareForSegue() method in your main view controller that looks for destination view controllers that conform to a protocol. Let's call it SensorDataListener . The main view controller could save those objects in an array and notify the objects about new sensor data using the methods in the protocol. (This last approach is similar to the approach of creating a SensorManager object, but instead it would be the main view controller serving that role.)

//At the top of your class:

protocol SensorDataListener {
   func newSensorData(_ SensorData)
}

var sensorClients = [SensorDataListener]()

//...

func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let dest = segue.desination as SensorDataListener {
       sensorClients.append(dest)
    }
}

And then when you receive new data

sensorClients.forEach { sensorClient in
  sensorClient.newSensorData(sensorData)
}

Have both of your child view controllers as variables in main view controller and hook them up from self.childViewControllers of main view controller in viewDidLoad like so.

class ViewController: UIViewController {

    var firstViewController: FirstViewController!
    var secondViewController: SecondViewController!

    override func viewDidLoad() {
        super.viewDidLoad()
        for vc in self.childViewControllers {
            if let firstViewController = vc as? FirstViewController {
                self.firstViewController = firstViewController
            }
            if let secondViewController = vc as? SecondViewController {
                self.secondViewController = secondViewController
            }
        }
    }

    func sensorDataUpdated(data: Any) {
        self.firstViewController.data = data
        self.secondViewController.data = data
    }
}

And here's an example of how one of your inner view controllers would work, the logic is the same for both of them:

class FirstViewController: UIViewController {
    var data: Any? {
        didSet {
            self.updateUI();
        }
    }
    func updateUI() {
        guard let data = self.data else { return }
        // Perform UI updates
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM