【问题标题】:How to call from a Popover a method of the main view controller?如何从 Popover 调用主视图控制器的方法?
【发布时间】:2017-04-24 19:38:45
【问题描述】:

在一个 iOS 项目中,我有一个主 ViewController 和一个第二个 ViewController,第二个 ViewController 显示为一个 Popover,并带有导航栏中按钮的 segue。在该弹出窗口中有一个带有此代码的按钮:

class Pop: UIViewController {

  @IBAction func colorOnePressed(_ sender: Any) {
        let vc = ViewController()
        vc. zoomIn()
    }

}

这是第一个视图控制器的方法:

class ViewController: UIViewController {

    @IBOutlet weak var mainTextField: UITextView!
    ...

    func zoomIn() {
        mainTextField.font = UIFont(name: "Helvetica Neue", size: CGFloat(18.00))
    }
}

不幸的是(显然对你们中的许多人来说)我收到了一个致命错误:“unexpectedly found nil while unwrapping an Optional value”。

【问题讨论】:

    标签: ios swift uiviewcontroller popover


    【解决方案1】:

    您正在尝试从 ViewController 的新实例中调用该方法。相反,您需要在 Popover VC 中声明一个 delegate 属性,并将 prepareForSegue:sender: 方法中的原始父 VC 作为您的 Popover VC 的委托传递。

    【讨论】:

      【解决方案2】:

      通过Aleksandr Medvedev 对这个问题的回答和TheAppMentor 对另一个问题的回答,我使用委托设计模式实现了这一点。如果它对某人有用,我会在代码下方发布。

      注意:我通常看到您使用 UIPopoverPresentationControllerDelegate 协议,但我创建了一个自定义协议 (ZoomProtocol),因此我可以包含我的方法 (zoomOut())。

      在主视图控制器中:

      import UIKit
      
      // declare a protocol, that lists variables and methods
      // the delegate is expected to respond to
      protocol ZoomProtocol {
          func zoomOut()
      }
      
      // set this view controller as the delegate
      class ViewController: UIViewController, ZoomProtocol { 
      
          ...
      
          // make your presenting view controller conform to the protocol
          zoomOut() {
              // do something
          }
      
          // pass the this view controller as a delegate for the Popover view controller
          override func prepare(for segue: UIStoryboardSegue, sender: Any?) {        
              if let pop = segue.destination as? PopViewController {
                  pop.delegate = self
              }
          }
      
      }
      

      在弹出视图控制器中:

      import UIKit
      
      class PopViewController: UIViewController {
      
          var delegate : ZoomProtocol?
      
          ...
      
          // when you want to, call the method on the presenting view controller
          @IBAction func zoomOutButtonPressed(_ sender: Any) {
              delegate?.zoomOut()
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        在父 View Controller 中,重写 prepare 以设置弹出框:

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "yourPopoverIdentifier" {
                let popoverVC = segue.destination
                popoverVC.modalPresentationStyle = UIModalPresentationStyle.popover
                popoverVC.popoverPresentationController!.delegate = self
            }
        }
        

        然后在子视图控制器中,您可以简单地调用presentingViewController 来访问父函数。在这种情况下,父级是默认的 View Controller,ViewController。

        @IBAction func buttonClick(_ sender: Any) {
            let parentVC = self.presentingViewController as! ViewController
            parentVC.functionOnParent()
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-26
          • 2013-07-02
          相关资源
          最近更新 更多