UIKit 中的 Segue 和委托

Segue and delegates in UIKit

我有 2 个控制器:MainVC 和 SideMenuVC。

我想使用 SideMenuVC 修改 MainVC,因此创建了 SideMenuVC 的委托(还有 Emdebed segue "name..." to "Side Menu View Controller" 在故事板上,因为 MainViewController 有子视图,其中包含 ContainerView - 这个容器是我们的 SideMenuVC。而这位代表按他应有的方式工作。

但是,由于应用程序中的逻辑,我还需要将数据从MAINVC发送到SIDEMENUVC.

所以我做了同样的事情 - 创建了第二个 VC 的另一个委托...但我发现,MainViewControllerDelegate 在 SideMenuViewController 中没有响应。而且我完全一无所知...

是的,我确实在两个 类 中实现了必要的协议!

下面两个VC的代码,附件中的故事板屏幕

MainViewController + MainViewControllerDelegate

protocol MainViewControllerDelegate{
    func isImageLoaded(_ isLoaded:Bool)
}

class MainViewController: UIViewController {
    /* ... */
    
    var delegate: MainViewControllerDelegate?
    var sideMenuViewController: SideMenuViewController?
    
    private var isSideMenuPresented:Bool = false
    private var isImageLoaded:Bool = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.isImageLoaded = false
        self.setupUI()
        self.delegate?.isImageLoaded(false)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "MainVC_SideMenuVC_Segue")
        {
            if let controller = segue.destination as? SideMenuViewController
            {
                self.sideMenuViewController = controller
                self.sideMenuViewController?.delegate = self
            }
        }
    }
/* ... */
//I'm using PHPicker, and when new image is selected, i want to send "true" via delegate
  func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        dismiss(animated: true)
        if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self){
            let previousImage = self.presentedImage.image
            itemProvider.loadObject(ofClass: UIImage.self){ [weak self] image, error in
                DispatchQueue.main.async {
                    guard let self = self, let image = image as? UIImage, self.presentedImage.image == previousImage else {
                        return
                    }
                    self.presentedImage.image = image
                    self.isImageLoaded = true;
                    self.delegate?.isImageLoaded(true)
                }
            }
        }
        
    }

SideMenuViewController + SideMenuViewControllerDelegate

protocol SideMenuViewControllerDelegate{
    func hideSideMenu() 
    func performAction(_ type:OperationType)
}

class SideMenuViewController: UIViewController {
/*...*/
    
    var delegate: SideMenuViewControllerDelegate?
    var mainViewController: MainViewController?
    
    private var menuData: [ExpandingCellModel] = []
    private var isImageLoaded: Bool = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
      //  self.mainViewController?.delegate = self
        menuData = setupData()
        setupUI()
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let controller = segue.destination as? MainViewController {
            controller.delegate = self
        }
    }
}

/* ... */

这是我认为正在发生的事情。

从 MainVC 到 SideMenuVC 有 发生 转场,但我认为 SideMenuVC 到 MainVC 之间没有转场 实际发生

Happening 是关键字,因为从 MainVC 到 SideMenuVC 有一个 EmbedSegue,但是从 SideMenuVC 到 MainVC 的 segue 在哪里?你在情节提要中做了一些连接,但在我看来没有发生

这就是为什么在 override func prepare 中按计划在 MainViewControllerDelegate 中调用并且委托正在设置但在 SideMenuViewController 中未设置的原因,因为 override func prepare 没有不会被调用,因为没有 segue 发生

您可以做的是在 MainViewControllerDelegate

中设置 prepare 中的两个代表
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "MainVC_SideMenuVC_Segue")
        {
            if let sideMenuVC = segue.destination as? SideMenuViewController
            {
                sideMenuVC.delegate = self
                
                // assign MainViewControllerDelegate here
                self.delegate = sideMenuVC
            }
        }
    }

现在检查数据是否也被发送回主视图控制器。

如果您的问题仍未解决,请查看并尝试this small example I set for you in github显示 mainVC 和 embeddedVC 之间传递的数据,它可能会给您一些提示。

您可以在此处查看此操作的结果:https://youtu.be/J7C7SEC04_E