如何使用故事板从 swift 中的弹出窗口访问父视图控制器

How to access parent view controller from popover in swift, using storyboard

在 UIViewController(splitviewcontroller 的详细视图)中按下 UIButton 会打开一个 UITableViewController,显示为弹出窗口。这是通过 segue 完成的,并且 "kind" 在属性检查器中设置为 "Present as Popover"。当 UITableViewController 中的 UITableViewCell 被选中时,我希望 UIViewController 捕捉到这个选择。

这就是我在 UITableViewController 中尝试做的事情:

 override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        let cell = tableView.cellForRowAtIndexPath(indexPath)
        let myViewController = presentingViewController as! MyViewController

        myViewController.variable = cell.someProperty
        self.dismissViewControllerAnimated(true, completion: nil)
    }

这在日志中给出:"fatal error: unexpectedly found nil while unwrapping an Optional value",表明我未能捕捉到parentview/presentingview。在阅读了弹出窗口之后,我觉得我应该在某个地方实现委托和委托方法。但我没能理解以及如何。

正确的做法是什么?

您可能想使用委托设计模式。如果我对您的情况的理解正确,您可以通过执行以下操作来实现:

class MyTableViewController: UITableViewController {
    // ...

    weak var myViewControllerDelegate: MyViewController? // Make sure it's weak! .. or you know what you're doing, haha

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // ...
        let property = 5 // cell.property
        self.myViewControllerDelegate?.myTableViewController(self, didSelectCellWithProperty: property)
    }
}

class MyViewController: UIViewController {
    // ...

    // In viewDidLoad or elsewhere, if necessary
    override func viewDidLoad() {
        super.viewDidLoad()
        //...

        myTableVCInstance.myViewControllerDelegate = self // This will set the delegate we created to self
    }

    func myTableViewController(viewController: MyTableViewController, didSelectCellWithProperty property: Int) {
        // ...
    }
}

请注意 myViewControllerDelegate 的命名,以免与 UITableViewController 已有的 delegate 冲突,后者属于 UITableControllerDelegate 类型。

这个例子是想说明一点。您可能希望使用协议来清理它。