2

A main view controller (M) is presenting a modal view controller (A). Another modal view controller (B) should be presented. The transition should be from (A) to (B) without (M) showing. After the transition to (B) the hidden (A) should be deinitialized. How can this be achieved?

I'm looking for a code based solution, Interface Builder / Storyboard is not used here.

Before tagging as duplicate: There are similar questions on SO which ask how to present a MVC from another another MVC, which is not my question.

Manuel
  • 14,274
  • 6
  • 57
  • 130

2 Answers2

1

Another answer, cause it is too long for comment.

Oh, now question is totally different. You cannot achieve what you desire in a way you mean. Since, documentation states that:

"For example, a full-screen presentation must be made by a view controller that itself covers the entire screen. If the current view controller is unable to fulfill a request, it forwards the request up the view controller hierarchy to its nearest parent, which can then handle or forward the request".

Therefore, you cannot deinitialize (A) with saving (B), if you presented B from A. A should be dismissed, to allow M present (A).

However, you can achieve it not by presenting modal view controller, but having childViewControllers [(A), (B)] in your M, and animating their appearances in (M), then just remove (A) when it is needed.

Bliss
  • 565
  • 4
  • 12
  • Can you give a code example on how to present child view controllers and animate their appearances? Also, I wonder why can't (M) present (B) over (A), because then (B) would have a parent that is (M) and it would fulfill the requirement you stated. However when I try to present (B) over (A) it does not appear. – Manuel Aug 24 '18 at 13:16
  • I think I found an example, if this is what you mean: https://stackoverflow.com/a/44753420/1870795 – Manuel Aug 24 '18 at 13:24
0

First of you shall understand that if you remove hidden modal View Controller (A), which presented your (B), then (B) also dismisses.

Since you asked to remove (A) from (B), then you need to pass parent of view controller, you wish to dismiss, in your case is (M) is parent for (A), so your (B), should know (M). Then, you do

(M).dismiss(animated: true, completion: nil)

which means view controller M will dismiss it's child view controller, which is (A) for your case.

The main point here is to call dismiss on parent view controller. Explanation could be found in description of dismiss provided by Apple (I highlighted parts, you should give your attention): -

*

Dismisses the view controller that was presented modally by the view controller. The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal. If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack. If you want to retain a reference to the view controller's presented view controller, get the value in the presentedViewController property before calling this method. The completion handler is called after the viewDidDisappear(_:) method is called on the presented view controller.

*

Bliss
  • 565
  • 4
  • 12
  • This is all clear to me, I updated my question to clarify the issue. I want to transition from (A) to (B) without (M) showing, then dismiss (A). Can I somehow make (M) present (B) over (A) and then dismiss (A)? – Manuel Aug 24 '18 at 12:39
  • @Manuel, I gave another answer, because stackoverflow does not allow to write long comments, check it – Bliss Aug 24 '18 at 13:05