Search code examples
swiftuiviewcontroller3dtouch

Peek ViewController but Pop a Different ViewController - 3D Touch - Swift


I want to peek a view controller that just has an ImageView and a few labels in it, but when the user presses harder they get popped into the ViewController that they would normally have been had the user just clicked on the table view cell!

The problem i have is that the viewControllerToCommit doesn't have an index path for me to work out what content to pass to the new View Controller. This is the code i have so far:

func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {

    let popViewController = self.storyboard?.instantiateViewController(withIdentifier: "ReadArticleViewController") as! ReadArticleViewController

    popViewController.storyURL = //This is where i need to be able to get the index path so i can extract the url for the webview

    self.show(popViewController, sender: self)

}

func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {

    guard let indexPath = tableView.indexPathForRow(at: location) else {return nil}

    let cell = tableView.cellForRow(at: indexPath) as! ArticleCell

    let previewViewController = self.storyboard?.instantiateViewController(withIdentifier: "PeekViewController") as! PeekViewController

    previewViewController.storyImage = cell.pictureView.image
    previewViewController.storyTitle = cell.titleLabel.text

    previewViewController.preferredContentSize = CGSize(width: view.frame.width, height: 300)
    previewingContext.sourceRect = cell.frame

    return previewViewController

}

Solution

  • In viewControllerForLocation, you had the index path and the cell. You need to save that information off to an instance property, as needed, so that you have it if commit is called. It would help particularly if this instance property were part of PeekViewController, because that is what is handed to you in commit (under the name viewControllerToCommit)! It already has a storyImage property and a storyTitle property; well, give it more properties, whatever you will need when commit arrives. In other words, use the PeekViewController as a messenger (or, looking at it another way, as an envelope). The instance that you returned from viewControllerForLocation is the instance you will receive in commit as viewControllerToCommit.