Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performing segue after sender view controller is dismissed

Tags:

ios

swift

Basically, I have a button in a slide-out menu (which is its own view controller that covers part of the Origin screen, let's call it Menu) that, when pressed, performs a modal segue to another controller, let's say Destination.

Is there any way that upon pressing the button in Menu (to go to Destination), that I can dismiss Menu back to Origin, and THEN segue to Destination?

It sounds silly but it's something that I think I've seen apps do before. In my case, the reason for wanting to do this is that once I press "Done" on Destination, it dismisses that controller back to Menu, when I want it to just dismiss back to Origin. I can't just perform a segue back to Origin from Destination.

Code:

This is how I open the Menu from Origin:

let interactor = Interactor()

@IBAction func openMenu(_ sender: AnyObject) {
    performSegue(withIdentifier: "openMenu", sender: nil)
}


@IBAction func edgePanGesture(sender: UIScreenEdgePanGestureRecognizer) {
    let translation = sender.translation(in: view)

    let progress = MenuHelper.calculateProgress(translationInView: translation, viewBounds: view.bounds, direction: .Right)

    MenuHelper.mapGestureStateToInteractor(
        gestureState: sender.state,
        progress: progress,
        interactor: interactor){
            self.performSegue(withIdentifier: "openMenu", sender: nil)
    }
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destinationViewController = segue.destination as? MenuViewController {
        destinationViewController.transitioningDelegate = self
        destinationViewController.interactor = interactor
        destinationViewController.currentRoomID = self.currentRoomID
    }
}

This is my prepareForSegue from Menu to Destination currently, nothing fancy:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    let inviteVC = segue.destination as! InviteVipViewController
    inviteVC.currentRoomID = self.currentRoomID
}

And finally to dismiss Destination is just a simple

@IBAction func cancelButtonPressed(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
}

I saw this question which is basically what I'm trying to do but there was no answer unfortunately: Performing segue after dismissing modal swift

Sorry if this sounds confusing, but if anyone knows what I'm talking about and can let me know how I can set up the segues/prepareForSegues to make it work, any input would be appreciated!

like image 980
KingTim Avatar asked Apr 20 '17 18:04

KingTim


1 Answers

Based on a modification to this answer, the following should work:

In your storyboard, remove the segue that is triggered by tapping your menu button and goes to Destination.

Create a new segue that goes from the Origin view controller to Destination view controller. This segue is going to be manually performed.

When your Destination option is selected in Menu, have Menu dismiss itself and then perform the Destination segue on Origin, like this:

    // This code goes in Menu, and you should call it when
    //    the menu button is tapped.
    //
    // presentingViewController is Origin
    weak var pvc = self.presentingViewController

    self.dismiss(animated: true) {

        // Menu has been dismissed, but before it is destroyed
        //  it calls performSegue on Origin
        pvc?.performSegue(withIdentifier: "openDestination", sender: nil)
    }

When Destination is dismissed, you should see Origin, without seeing Menu at all.

I tested this in a sample app where "Menu" was not a slide out, but a full modal view controller, and it worked for me.

EDIT: While troubleshooting with @KingTim, he found that we needed to wire the segue from the UINavigationController, not Origin, to the Destination. This is because Origin is inside a navigation controller. After that discovery, it worked.

like image 111
Mike Taverne Avatar answered Oct 21 '22 20:10

Mike Taverne