Как изменить UIColor в Embeded контроллер от родительского контроллера? - PullRequest
0 голосов
/ 11 февраля 2020

Я новичок в Swift и в настоящее время поддерживаю Делегатов . Мне нужно поменять встроенный контроллер UIColor с кнопки на родительском контроллере.

Вот что я пробовал

1) Я создал протокол делегата с забавой c и UIColor как arumetn 2) Добавить экземпляр в Parent V C (ThirdViewController)

Код в родительском V C

    import UIKit

protocol TVCDelegate: class {
    func setColor(color: UIColor)
}

class ThirdViewController: UIViewController {

    weak var delegate: TVCDelegate?


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? AdditionalThirdViewController {
            vc.setColor(color: UIColor.red) }}

    @IBAction func redButton(_ sender: Any?) {
        I need this button to change color in **Embedded VC** }

    override func viewDidLoad() {
        super.viewDidLoad() }


    }


}

extension ThirdViewController: TVCDelegate {
    func setColor(color: UIColor) {
        view.backgroundColor = color
    } }

Код во встроенном v c

import UIKit

class AdditionalThirdViewController: UIViewController {


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? ThirdViewController {
            vc.delegate = self } }

    @IBAction func redButton(_ sender: Any) {
    }

    override func viewDidLoad() {
        super.viewDidLoad()

Наконец, мне нужно, чтобы на обоих контроллерах было по три кнопки, и каждая из них меняла цвет в другом контроллере.

Как мне этого добиться? А также у вас есть рекомендации, что читать о делегатах для чайников?

Ответы [ 3 ]

1 голос
/ 11 февраля 2020

Я настоятельно рекомендую вам прочитать эту статью подробно и понять, как работает делегат и данные о

https://medium.com/@jamesrochabrun / реализовать-делегаты-в-быстром-пошаговом-d3211cbac3ef

В вашем случае вы должны вызывать метод делегата, когда кнопка нажата в вашем ThirdViewController, как это.

@IBAction func redButton(_ sender: Any?) {
   delegate?.setColor(UIColor.red)
}

приведенный выше код вызовет метод делегата со значением red. Теперь вам нужно перехватить это значение в EmbededViewController и реализовать TVCDelegate следующим образом:

extension AdditionalThirdViewController: TVCDelegate {
    func setColor(color: UIColor) {
    //Set Color sent by ThirdViewController
    }
}

Опять же, вам необходимо понять основы делегирования.

Дополнительно удалите этот код, который вы написали в ThirdViewController

extension ThirdViewController: TVCDelegate {
    func setColor(color: UIColor) {
        view.backgroundColor = color
    } }

Класс, который объявляет делегат, не может реализовать тот же делегат.

0 голосов
/ 12 февраля 2020

Чтобы попытаться дать немного больше разъяснений ...

Шаблон разработки протокола / делегата позволяет нам "делегировать" работу другому классу / объекту.

Очень часто используемый случай - там, где люди даже не осознают, что используют его - это с табличными представлениями. Само табличное представление определяет, когда пользователь нажимает на строку, а затем сообщает своему делегату , что только что произошло. В этот момент табличное представление не знает, какое действие следует предпринять на основе выбора строки ... оно просто сообщает своему делегату (контроллеру табличного представления):

"Привет! Пользователь выбрал один из моих рядов! "

и контроллер соответствует этому протоколу путем реализации:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // do something because a row was selected
}

В этой реализации мы знаем кто отправляет это сообщение (tableView), и мы знаем, какая строка была выбрана (indexPath). Самому табличному представлению не нужно ничего знать о содержимом строки или о том, что должно произойти дальше ... оно делегирует этой задаче контроллеру.

В вашем случае вы хотите загрузить контроллер представления в представление контейнера, и чтобы кнопки в этом контроллере сообщали своему делегату (родительскому контроллеру) «нажата кнопка» и позволяли родительскому контроллеру решать, что делать - например, изменить цвет фона.

Для кнопок в родительском контроллере представления вы просто должны установить свойство .backgroundColor представления контейнера V C, или, по выбору, вызовите функцию в этом контроллере.

Я собрал простой, очень похожий пример этого пару лет go и просто обновил его, чтобы лучше отразить то, что вы пытаетесь сделать. Вы можете найти его здесь: https://github.com/DonMag/ContainerDelegate

Это выглядит так:

enter image description here

Нажатие на Cyan или оранжевые кнопки (в главном контроллере) изменят фон V C в представлении контейнера.

Нажатие на красную или зеленую кнопку в представлении контейнера скажет его делегату :

"Эй! Нажата цветная кнопка!"

и функция делегата (в главном контроллере) изменит цвет фона большой метки.

0 голосов
/ 11 февраля 2020

Вам необходимо зарегистрировать уведомление и позвонить ему. Позвольте мне объяснить вам, как вы можете сделать это первым нажатием кнопки на первом viewcontroller добавить этот код:

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "changeColor"), object: nil, userInfo: nil)

После добавления этого кода go в третий контроллер представления и в viewwillappear добавить этот код:

 NotificationCenter.default.addObserver(self, selector: #selector(YOURVIEWCONTROLLERNAME.changeColor(notification:)), name: Notification.Name(rawValue: "changeColor"), object: nil) 

после этого добавьте этот метод в третий контроллер вида

 @objc func changeColor(notification: NSNotification)
    {
        self.view.backgroundColor = .red
    }

Теперь все готово.

...