简体   繁体   中英

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

Pushing a UIButton in a UIViewController (detailview of a splitviewcontroller) opens a UITableViewController, presented as a popover. This is accomplished by a segue, and "kind" is set as "Present as Popover" in attributes inspector. When a UITableViewCell in the UITableViewController is selected, I want the UIViewController to catch this selection.

This is what I am trying to do in the 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)
    }

This gives in the log: "fatal error: unexpectedly found nil while unwrapping an Optional value", indicating that I fail to catch the parentview/presentingview. After reading about popovers, I feel I should implement a delegate and delegate methods somwhere. But I fail to undersetand how.

What is the correct way to do this?

You probably want to use the delegation design pattern. If I understand your situation correctly, you can accomplish that by doing something like:

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) {
        // ...
    }
}

Note the naming of myViewControllerDelegate so as not to clash with the delegate that UITableViewController already has, which would be of type UITableControllerDelegate.

This example is intended to show a point. You would probably want to use a protocol to clean it up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM