6

My goal is to present a view controller without dismissing directly to its presentingViewController.

To make it more clear, consider the following example:

Referring to this storyboard:

enter image description here

Assuming that the first black view controller is the first (initial) one, it should present the third white view controller; The issue is the white view controller should dismisses to the second orange view controller but not the black one, so it should behave like:

  • Black VC Presents White VC.
  • White VC Dismisses to Orange VC.
  • Orange VC Dismisses to Black VC.

How to apply such a behavior?

Remark: There is no navigation controller, it should be present/dismiss, not push/pop.

Ahmad F
  • 26,570
  • 13
  • 76
  • 124
  • Do you want the standard "slide-up on present, slide-down on dismiss" animations? – DonMag May 02 '17 at 15:21
  • @DonMag regardless what's the animation. Yes, the default animation would be good – Ahmad F May 02 '17 at 15:23
  • Couple options... 1) Embed in `UINavigationController`, but don't show the Navigation Bar -- just use the push/pop stack management. 2) Black presents Orange... on load, Orange adds White as a childVC / subview... on button tap, Orange animates White away... on another button tap, Orange is dismissed. – DonMag May 02 '17 at 15:53
  • @DonMag Thank you for your comment. I would like to invite you to check [my answer](http://stackoverflow.com/a/43742297/5501940) and provide your opinion. – Ahmad F May 02 '17 at 15:56

5 Answers5

6

This could be achieved by letting the first black view controller to present the second orange view controller and then the orange view controller should present the third white view controller.

But this arises an issue which is: the end-user will clearly notice that there are two view controllers have been sequentially presented. For solving this, you will need to do a pretty simple trick which is to take a screenshot from the first view controller and passing it to the second view controller to display it while presenting the third view controller.

You can check this repository to see how it is exactly could be done (Swift 3).

The final output would be:

enter image description here

Ahmad F
  • 26,570
  • 13
  • 76
  • 124
  • Hmmm... you don't really need to jump through the "screenshot" hoops. See my answer for another way to do it. – DonMag May 02 '17 at 16:15
2

Here is one method...

  1. Black presents Orange
  2. In viewDidLoad, Orange instantiates White as a childVC and adds White's view as a 'full-screen' subview.
  3. On button tap in White, White's view is animated away and removed from the hierarchy.
  4. On button tap in Orange, Orange is dismissed, returning user to Black.

enter image description here

Here is method two...

  1. Embed Black in a NavigationController without navigation bar
  2. On tap in Black, instantiate Orange and White VCs
  3. Call .setViewControllers:animated: to "stack the views" on the navigation controller, and jump directly to the last view.
  4. After that, navigation backwards uses the standard .popViewController functionality.

enter image description here

You can view a working example of both methods here: https://github.com/DonMag/SkipNavigation

DonMag
  • 44,662
  • 5
  • 32
  • 56
  • Well, do you think that is this a better approach? in my opinion, I find it kind of complex to achieve such a thing. Thank you in advance btw :) – Ahmad F May 02 '17 at 16:35
  • I added a second method - using a navigation controller *without* navigation bar. Allows for more standard push/pop type navigation. – DonMag May 02 '17 at 16:40
  • Which approach is better? Tough to say... I would *think* doing screen-grabs and passing between controllers could get messy, depending on what else needs to be done. Also, maybe not real efficient on high-res devices? – DonMag May 02 '17 at 16:41
1

If the black VC presents both the orange and immediately the white, you'll have the structure you're looking for. You can turn off animations so that the orange would probably not be visible.

Owen Hartnett
  • 5,827
  • 2
  • 17
  • 34
  • Thank you for your answer. I would like to invite you to check [my answer](http://stackoverflow.com/a/43742297/5501940) and provide your opinion, it is almost what you mentioned... – Ahmad F May 02 '17 at 15:58
  • It's the animation from black to orange to white which makes it noticeable. Remove that and it's instantaneous. – Owen Hartnett May 03 '17 at 13:20
1

The most simple solution I can think is to hide the OrangeViewController and then show it when the WhiteViewController has been shown using the completion callback of present(_:animated:completion:) using this code on the button action.

@IBAction func goToWhite(_ sender: UIButton) {
    let orangeViewController = storyboard?.instantiateViewController(withIdentifier: "OrangeViewController")
    orangeViewController?.view.isHidden = true
    present(orangeViewController!, animated: false)

    let whiteViewController = storyboard?.instantiateViewController(withIdentifier: "WhiteViewController")
    orangeViewController?.present(whiteViewController!, animated: true) {
        orangeViewController?.view.isHidden = false
    }
}
avilin
  • 11
  • 2
  • This will not leads to the desired results, as I mentioned in [my answer](http://stackoverflow.com/a/43742297/5501940) the end-user will clearly notice that there are two view controllers have been sequentially presented. I invite you to check my answer :) – Ahmad F May 02 '17 at 16:32
  • I hide the OrangeViewController before presenting it, so the user doesn't see its content during the WhiteViewController animation, and presenting it with "animated: false" remove the animation delay, so it appears as if the app is only showing the WhiteViewController. – avilin May 02 '17 at 17:18
-2

you can append navigation controller to the first controller. Then on click of first view controller you can set all the view controllers in whatever order you want by using this code

   var viewControllers = self.navigationController.viewControllers.mutable
   / * Now you can append the other 2 controllers to this array */
      viewControllers.append(yellowVC);
      viewControllers.append(whiteVC);
      self.navigationController.setViewCOntrollers(viewCOntrollers.animated:YES);

You can also change the order of popping the viewCOntrollers by using the above code.

varender singh
  • 315
  • 3
  • 4