Swift. Запуск функции в одном VC из другого VC

В файле ViewController.swift есть два класса для контроллеров в main.storyboard - weekController и monthController.

По нажатию кнопки в monthController должна активироваться функция reinitializeMonth() в контроллере weekController, после monthController должен исчезнуть

Вот так я пытался это реализовать.

class monthController: UIViewController {
    @IBOutlet var buttons: [UIButton]!

    @IBAction func buttonPressed(_ sender: UIButton) {
        selectedMonth.month = String(sender.tag)
        weekController().reinitializeMonth()
        dismiss(animated: true, completion: nil)
    }


    override func viewDidLoad() {
    }

}

Но сразу выдаёт ошибку

Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

на строчке

monthLabel.text = monthDict[month]!

Лейбл в weekController


Ответы (1 шт):

Автор решения: schmidt9

Вы не совсем правильно организуете взаимодействие между вью контроллерами

Во-первых, по поводу стиля - вью контроллеры лучше держать в разных файлах и имена классов в Swift пишутся с большой буквы.

Во-вторых, касательно способов передачи данных между вью контроллерами. Есть разные способы, можете почитать самостоятельно, информации много, в вашем случае для передачи результата действия обратно в вызывающий вью контроллер можно использовать например (1) делегирование и (2) блок completion. При 2 способе данные придется сохранить в промежуточное хранилище, так как блок здесь не может иметь параметров.

Ваша ошибка состоит в том, что вы создаете экземпляр weekController заново вместо сохранения ссылки на уже существующий экземпляр

weekController().reinitializeMonth()

Пример

class WeekViewController: UIViewController {

    @IBOutlet var monthLabel: UILabel!

    @IBAction func showMonthViewControllerButtonTouchUpInside(_ sender: UIButton) {
        let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(identifier: "monthViewControllerIdentifier") as! MonthViewController
        // способ 1
        vc.delegate = self

        // способ 2
        vc.completion = {
            self.monthLabel.text = UserDefaults.standard.string(forKey: "some_data")
        }

        present(vc, animated: true, completion: nil)
    }

}

extension WeekViewController : MonthViewControllerDelegate {

    func monthViewControllerWillDismiss(_ monthViewController: MonthViewController, with data: String) {
        monthLabel.text = data
    }

}

Возвращаем данные

protocol MonthViewControllerDelegate : class {

    func monthViewControllerWillDismiss(_ monthViewController: MonthViewController, with data: String)

}

class MonthViewController: UIViewController {

    // способ 1
    weak var delegate: MonthViewControllerDelegate?

    // способ 2
    var completion: (() -> Void)?

    @IBAction func dismissButtonPressed(_ sender: UIButton) {
        delegate?.monthViewControllerWillDismiss(self, with: "some data")

        UserDefaults.standard.set("some data", forKey: "some_data")
        dismiss(animated: true, completion: completion)
    }

}
→ Ссылка