【问题标题】:What's the syntax for setting a Swift Delegate to a view controller other than "self"?将 Swift Delegate 设置为“self”以外的视图控制器的语法是什么?
【发布时间】:2014-12-01 05:04:51
【问题描述】:

我有一个简单的程序,其中包含导航控制器和创建的序列以在 3-5 个屏幕之间切换。数据在主视图控制器中,并且我在主视图控制器和第二个视图控制器之间正确设置了委托和协议。我遇到的问题是我不确定如何在主视图和第三个视图之间设置适当的委托。我的主要问题是覆盖 prepareForSegue 函数。

因为程序一次流过一个屏幕(主视图转到第二个视图,第二个视图转到第三个视图等)我不确定应该在哪里以及如何使用此功能。我已将主视图设置为遵守第三视图控制器协议,但我只是不确定如何将其设置为委托。

例如,我知道如果我在第二个视图控制器中重写 prepareForSegue 函数,我不能使用“self”作为委托。我想让主视图成为委托,但我不确定让非“自我”视图成为委托的语法是什么。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "2ndViewTo3rdView"{
        let thirdVC:ThirdViewController = segue.destinationViewController as ThirdViewController
        thirdVC.delegate = (????)
    }
}

我尝试了类似“navigationController?.topViewController”的内容,但出现以下错误:类型“UIViewController”不符合协议“ThirdViewDelegate”

在这方面的任何帮助将不胜感激。

【问题讨论】:

    标签: ios swift uiviewcontroller delegates protocols


    【解决方案1】:

    我已将此解决方案用于模态呈现的 VC,其中:

    • customVCOneA 可能会显示 customVCThree
      -或者-
    • customVCOneB 可能会显示 customVCtwo
      -然后-
    • customVCtwo 呈现 customVCThree
    • customVCThree 仅发送指令以清除 customVCOneB 上的表单数据。

    对于 Swift 5:

    在customVCThree(发送指令或信息)

    课外:

    // Establish protocol for communicaiton back to parent view controller.
    protocol ClearVCOneBProtocol {
    
        // State the method that communicates back to grandparent view controller.
        func clearVCOneB(/*Other Desired Parameters*/)
    
    }
    

    类内部(不在任何函数中):

    // Declare the delegate used to communicate with parent view controller.
    var delegate: ClearVCOneBProtocol?
    

    类内部(应用所需的触发协议方法):

        // As View Controller is about to disappear.
        override func viewWillDisappear(_ animated: Bool) {
    
            // Check "Restoration Identifier" (set inside Interface Builder or by code).
            if presentingViewController?.restorationIdentifier == "customVCTwo" {
    
                // Instruct the delegate to clear the form.
                delegate?.clearVCOneB()
    
            }
            else {
    
                // Do NOT instruct the delegate to clear the form.
    
            }
    
        }
    

    在customVCOneB中(接收指令或信息)

    课外:

    // Extend the View Controller with the protocol and delegate methods.
    extension customVCOneB: ClearVCOneBProtocol {
    
        // Conform to ClearVCOneBProtocol protocol.
        func ClearVCOneBProtocol(/*Other Desired Parameters*/) {
    
            // Call a function that has been declared inside customVCOneB and/or access parameters included in protocol.
            resetForm()
    
        } // End ClearVCOneBProtocol.
    
    } // End extension.
    

    在 customVCTwo 中(customVCOneB 和 customVCThree 之间的中介)

    customVCThree 在哪里被实例化和呈现:

        // Create the View Controller.
        let newVC = self.storyboard?.instantiateViewController(withIdentifier: customVCThree) as! customVCThreeViewController
    
        // If customVCTwo was presented by customVCOne...
        if presentingViewController?.restorationIdentifier == "customVCOneB" {
    
            // Set customVCOneB as the delegate of customVCThree.
            customVCThree.delegate = presentingViewController as! customVCOneBViewController
    
        }
    

    【讨论】:

      【解决方案2】:

      你试过了吗?

      navigationController?.topViewController as? YourClassThatConformsToThirdViewDelegate

      您需要将 YourClassThatConformsToThirdViewDelegate 替换为您案例中的相关类。

      关键是as? YourClassThatConformsToThirdViewDelegate 部分。 UIViewController 显然不符合 ThirdViewDelegate,所以我觉得强制转换可以解决问题。

      【讨论】:

      • 我试过了,但是当我尝试在 ThirdViewController 中使用委托函数(例如“delegate!.protocolFunction”时,它仍然给我一个“致命错误:在展开可选值时意外发现 nil”) (字符串变量)”我认为这是因为委托没有被分配给它并且出现为零?类似的代码在第二个视图中,并且使用“self”标签正确运行,所以我相信它似乎围绕着正确设置委托。
      • 我会检查 navigationController.viewControllers 的内容并弄清楚发生了什么。也许,topViewController 没有给你想要的 viewController。但是,这只是一个猜测!
      【解决方案3】:

      我遇到了类似的问题,为了其他人需要其他答案,你去吧。我通过将接收 VC 作为 prepare(forSegue:) 中的参数传递给变量来解决了这个问题。

      if let secondVC = (segue.destination as? UINavigationController)?.topViewController as? CustomViewController {
                  secondVC.firstVC = self
              }
      

      然后在我的 secondVC 中,创建一个第三个VC 的实例,我希望它具有这样的委托:

      let thirdVC = storyboard.instantiateViewController(withIdentifier: "thirdVC") as? ThirdViewController
              thirdVC?.Delegate = firstVC.self as! Delegate
      

      希望这对某人有所帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-11
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        • 2018-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多