Как мне постоянно отправлять данные из родительского ViewController в ContainerViewController - PullRequest
0 голосов
/ 14 октября 2018

В моем приложении основной ViewController получает данные с датчика 60 раз в секунду.Для отображения данных у меня есть два объекта ContainerView: один отображает необработанные данные, а другой отображает их в виде графика.

enter image description here

Как сделатьЯ либо постоянно отправляю данные из моего mainVC в ContainerView, либо позволяю ContiainerViews обращаться к переменным в моем mainVC?

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

Иметь оба ваших дочерних контроллера вида в качестве переменных в контроллере основного вида и подключать их из self.childViewControllers контроллера основного вида в viewDidLoad следующим образом.

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
    }
}

И вот пример того, какодин из ваших внутренних контроллеров представления будет работать, логика одинакова для них обоих:

class FirstViewController: UIViewController {
    var data: Any? {
        didSet {
            self.updateUI();
        }
    }
    func updateUI() {
        guard let data = self.data else { return }
        // Perform UI updates
    }
}
0 голосов
/ 14 октября 2018

Есть много способов нарезать это.

Я бы не советовал собирать эти данные с ваших датчиков в контроллере вида.Это не совсем работа контроллера представления.Хуже, когда есть несколько объектов, которым нужны данные датчика.

Вероятно, самым чистым дизайном было бы создание отдельного объекта (я назову его SensorManager), который собирает данные вашего датчика и передает их всем, кому небезразлично.

Возможно, у вас есть SensorManager используйте NotificationCenter для трансляции уведомлений, а затем попросите все заинтересованные объекты добавить наблюдателей для уведомлений, которые им нужны.Это дает вам очень слабую связь между SensorManager и объектами, которые получают уведомления о данных датчика.Недостатком является то, что код сложнее отлаживать.

С другой стороны, вы можете настроить SensorManager на массив объектов, о которых он уведомляет.Я бы определил протокол, который имеет один или несколько методов, которые вызываются с данными датчика, и чтобы SensorManager поддерживал массив клиентских объектов, которые соответствуют этому протоколу.Когда SensorManager имеет новые данные датчика, он будет проходить через массив клиентских объектов и вызывать соответствующий метод для каждого, чтобы сообщить каждому о новых данных.Этот второй вариант в некотором роде похож на шаблон проектирования делегатов, но это один-ко-многим, где шаблон делегата представляет собой передачу информации один на один.

Если вы преданы идеесобирая данные датчика в вашем главном контроллере представления, и вы создаете свои дочерние контроллеры представления, используя встраиваемые сегменты, тогда вы можете написать prepareForSegue() метод в вашем главном контроллере представления, который ищет целевые контроллеры представления, которые соответствуют протоколу.Давайте назовем это SensorDataListener.Контроллер основного представления может сохранять эти объекты в массиве и уведомлять объекты о новых данных датчика, используя методы в протоколе.(Этот последний подход аналогичен подходу создания SensorManager объекта, но вместо этого он будет основным контроллером представления, выполняющим эту роль.)

//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)
    }
}

А затем, когда вы получите новые данные

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