Делегат не работает с контейнером ViewController

В моем MainViewController я установил кнопку и представление контейнера, которое содержит SecondViewController:

let secondViewController = SecondViewController()
secondViewController.willMove(toParent: self)
containerView.addSubview(secondViewController.view)
secondViewController.view.frame = containerView.bounds
secondViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.addChild(secondViewController)
secondViewController.didMove(toParent: self)

Я настроил свой протокол делегирования:

protocol SayHiDelegate {
    func sayHi()
}

Внутри MainViewController:

var delegate: SayHiDelegate?

@objc func buttonTapped() {
    delegate?.sayHi()
}

Я настроил функцию делегата в своем SecondViewController.

func sayHi() {
    label.text = "HI"
}

В SecondViewcontroller viewDidLoad:

let vc = MainViewController()
vc.delegate = self

В этом проекте я не использовал раскадровку. Проблема в том, что когда я нажимаю кнопку в моем MainViewController, функция делегата вызывается, но не работает. Я думаю, что проблема должна заключаться в использовании представления контейнера и функции делегата. Здесь скачать проект. Любые подсказки? Спасибо


person Edoardo    schedule 14.07.2019    source источник
comment
вы должны использовать делегат, если SecondViewController необходимо уведомить MainViewController, а не наоборот.   -  person Gustavo Vollbrecht    schedule 14.07.2019
comment
@GustavoVollbrecht Почему? это неправильно?   -  person Edoardo    schedule 14.07.2019
comment
Как вы ожидаете, что delegate? будет иметь значение от ?? назначил это ?? это ноль, поэтому код не срабатывает внутри второго vc, на него нет ссылки   -  person Sh_Khan    schedule 14.07.2019
comment
@Sh_Khan Мне нужно передавать данные между ViewControllers, поэтому я решил использовать делегат. У MainViewController есть данные, которые нужны SecondViewControllers.   -  person Edoardo    schedule 14.07.2019
comment
@EdoardodeCal Лучший способ уведомить один контроллер другому с помощью делегата. используйте делегат как слабый для предотвращения цикла сохранения.   -  person SGDev    schedule 14.07.2019
comment
всегда думайте от точки отправителя в том, как вы получаете ссылку на получателя   -  person Sh_Khan    schedule 14.07.2019


Ответы (2)


Поскольку вам нужно вызвать дочерний элемент от родителя, то здесь нет необходимости в делегате, сделайте это переменной экземпляра внутри MainViewController

let secondViewController = SecondViewController()

затем используйте его для вызова

secondViewController.sayHi()
person Sh_Khan    schedule 14.07.2019

Добавьте эту строку в свой код

self.delegate = secondViewController

Убедитесь, что вы делегируете nil, потому что вы не назначаете ссылку на secondViewController.

person SGDev    schedule 14.07.2019
comment
оператор пытается вызвать второй из основного, а не наоборот - person Sh_Khan; 14.07.2019
comment
@SumitGarg спасибо, но ранее я установил в своем SecondViewController: let vc = MainViewController() vc.delegate = self, и это не сработало. Используя ваш код, он работает, почему? - person Edoardo; 14.07.2019
comment
не могли бы вы уточнить, какой тип ссылки является самостоятельным, это тип SecondViewController? - person SGDev; 14.07.2019