Делегат равен нулю при использовании представлений контейнера

У меня есть 2 представления контейнеров, в которые встроены UITableViewController (sideMenuVC) и UICollectionViewController (centerVC) соответственно, а мой CollectionVC находится внутри самого навигационного контроллера. Я поместил эти два Container View в третий VC, который является корневым VC. Теперь я пытаюсь показать содержимое в моем centerVC на основе строки, выбранной в sideMenuVC, и я использую делегатов, однако делегат равен нулю, когда я пытаюсь вызвать его из отправителя. Я попытался установить делегат как слабый, а также установить делегат в awakeFromNib вместо viewDidLoad, я также попытался установить делегата из разных VC.

Вот мой протокол:

import Foundation
import Photos

protocol sideMenuDelegate {
    func handleRowSelection(title: String, fetchResult: PHFetchResult<PHAsset>, assetCollection: PHAssetCollection?)
}

и вот как я устанавливаю делегат внутри третьего VC, который содержит оба представления контейнера:

let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
sideMenuVC = storyboard.instantiateViewController(withIdentifier: "sideVC") as? SideMenuViewController
centerVC = storyboard.instantiateViewController(withIdentifier: "centerVC") as? centerViewController
sideMenuVC?.delegate = centerVC

Я также попытался установить его в моем centerVC следующим образом:

let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
sideMenuVC = storyboard.instantiateViewController(withIdentifier: "sideVC") as? SideMenuViewController
sideMenuVC?.delegate = self

и, наконец, это реализация функции делегата:

extension centerViewController: sideMenuDelegate {
    func handleRowSelection(title: String, fetchResult: PHFetchResult<PHAsset>, assetCollection: PHAssetCollection?) {
        pageTitle = title
        inFetchResult = fetchResult
        inAssetCollection = assetCollection
    }  
}

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


person HemOdd    schedule 16.03.2019    source источник
comment
Я подозреваю, что ваше последнее предложение может быть правильным. Делаете ли вы что-нибудь, чтобы подключить объект sideMenuVC к иерархии контроллера представления после создания экземпляра... или это делается посредством обычной загрузки раскадровки?   -  person Phillip Mills    schedule 16.03.2019
comment
Нет. Я настроил все в раскадровке, и я просто использую данный код, чтобы запустить экземпляр через раскадровку, которая не работает. Я не мог найти никакого другого кода для этой цели.   -  person HemOdd    schedule 16.03.2019
comment
Я не могу подробно рассказать о том, что вижу, но вам не нужно создавать ничего нового. Вместо этого вы должны установить соединение делегата, получая ссылки на правильные контроллеры, когда они загружаются раскадровкой. Или... можете ли вы установить соединение с делегатом внутри раскадровки?   -  person Phillip Mills    schedule 16.03.2019
comment
Подключение с помощью раскадровки не работает, поэтому я пытаюсь сделать это с помощью кода. Вы знаете какой-нибудь другой код, который может работать?   -  person HemOdd    schedule 17.03.2019
comment
и под использованием раскадровки я имею в виду установку свойства делегата как IBOutlet и подключение его с помощью управления + перетаскивания.   -  person HemOdd    schedule 17.03.2019


Ответы (1)


Я нашел решение.

При использовании Container Views правильный способ получения ссылок на встроенные VC — реализовать метод Prepare for segue и получить доступ к свойству назначения внутри класса VC, содержащего Container Views; вот так:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "sideVCSeg" {
            sideMenuVC = (segue.destination as! SideMenuViewController)
        }
        if segue.identifier == "centerVCSeg" {
            let navController = (segue.destination as! UINavigationController)
            centerVC = (navController.viewControllers.first as! centerViewController)
        }
    }

и поскольку этот метод выполняется при загрузке представления, мне нужно было только добавить эту строку в viewDidLoad:

sideMenuVC?.delegate = centerVC
person HemOdd    schedule 16.03.2019