Dismiss all modals in iOS with Swift 4










2















I am trying to achieve a navigation similar to the Netflix app for iOS. When you click on a movie, a modal window pops up with a close button. If within this movie I choose to see another movie then the second modal pops up and in addition to the close button, a back button appears. I can use the back button to dismiss one by one and the close button to return to the base screen.



I am able to dismiss a single view using



dismiss(animated: true, completion: nil)


but how can I return to the base screen closing all modals at once? Also, is modals the way to go? I chose this because I didn't want the navigation bar on top.



I'm working with Swift 4.2 in Xcode 10.










share|improve this question






















  • you can done by creating protocols to dismiss but it will be long process

    – wings
    Nov 15 '18 at 13:41











  • Well, the first view controller that appears when you click on a movie, the source presents it by embedding it in a UINavigationController. Then, when you click another movie, it is a push transition of that navigation controller. The close button just uses the default dismiss(animated:completion) that you mentioned.

    – nayem
    Nov 15 '18 at 16:05











  • Why not doing a delegate to dismiss from the VC?

    – ironRoei
    Nov 19 '18 at 11:42















2















I am trying to achieve a navigation similar to the Netflix app for iOS. When you click on a movie, a modal window pops up with a close button. If within this movie I choose to see another movie then the second modal pops up and in addition to the close button, a back button appears. I can use the back button to dismiss one by one and the close button to return to the base screen.



I am able to dismiss a single view using



dismiss(animated: true, completion: nil)


but how can I return to the base screen closing all modals at once? Also, is modals the way to go? I chose this because I didn't want the navigation bar on top.



I'm working with Swift 4.2 in Xcode 10.










share|improve this question






















  • you can done by creating protocols to dismiss but it will be long process

    – wings
    Nov 15 '18 at 13:41











  • Well, the first view controller that appears when you click on a movie, the source presents it by embedding it in a UINavigationController. Then, when you click another movie, it is a push transition of that navigation controller. The close button just uses the default dismiss(animated:completion) that you mentioned.

    – nayem
    Nov 15 '18 at 16:05











  • Why not doing a delegate to dismiss from the VC?

    – ironRoei
    Nov 19 '18 at 11:42













2












2








2








I am trying to achieve a navigation similar to the Netflix app for iOS. When you click on a movie, a modal window pops up with a close button. If within this movie I choose to see another movie then the second modal pops up and in addition to the close button, a back button appears. I can use the back button to dismiss one by one and the close button to return to the base screen.



I am able to dismiss a single view using



dismiss(animated: true, completion: nil)


but how can I return to the base screen closing all modals at once? Also, is modals the way to go? I chose this because I didn't want the navigation bar on top.



I'm working with Swift 4.2 in Xcode 10.










share|improve this question














I am trying to achieve a navigation similar to the Netflix app for iOS. When you click on a movie, a modal window pops up with a close button. If within this movie I choose to see another movie then the second modal pops up and in addition to the close button, a back button appears. I can use the back button to dismiss one by one and the close button to return to the base screen.



I am able to dismiss a single view using



dismiss(animated: true, completion: nil)


but how can I return to the base screen closing all modals at once? Also, is modals the way to go? I chose this because I didn't want the navigation bar on top.



I'm working with Swift 4.2 in Xcode 10.







ios swift modalviewcontroller






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 '18 at 13:21









cesarcarloscesarcarlos

4151317




4151317












  • you can done by creating protocols to dismiss but it will be long process

    – wings
    Nov 15 '18 at 13:41











  • Well, the first view controller that appears when you click on a movie, the source presents it by embedding it in a UINavigationController. Then, when you click another movie, it is a push transition of that navigation controller. The close button just uses the default dismiss(animated:completion) that you mentioned.

    – nayem
    Nov 15 '18 at 16:05











  • Why not doing a delegate to dismiss from the VC?

    – ironRoei
    Nov 19 '18 at 11:42

















  • you can done by creating protocols to dismiss but it will be long process

    – wings
    Nov 15 '18 at 13:41











  • Well, the first view controller that appears when you click on a movie, the source presents it by embedding it in a UINavigationController. Then, when you click another movie, it is a push transition of that navigation controller. The close button just uses the default dismiss(animated:completion) that you mentioned.

    – nayem
    Nov 15 '18 at 16:05











  • Why not doing a delegate to dismiss from the VC?

    – ironRoei
    Nov 19 '18 at 11:42
















you can done by creating protocols to dismiss but it will be long process

– wings
Nov 15 '18 at 13:41





you can done by creating protocols to dismiss but it will be long process

– wings
Nov 15 '18 at 13:41













Well, the first view controller that appears when you click on a movie, the source presents it by embedding it in a UINavigationController. Then, when you click another movie, it is a push transition of that navigation controller. The close button just uses the default dismiss(animated:completion) that you mentioned.

– nayem
Nov 15 '18 at 16:05





Well, the first view controller that appears when you click on a movie, the source presents it by embedding it in a UINavigationController. Then, when you click another movie, it is a push transition of that navigation controller. The close button just uses the default dismiss(animated:completion) that you mentioned.

– nayem
Nov 15 '18 at 16:05













Why not doing a delegate to dismiss from the VC?

– ironRoei
Nov 19 '18 at 11:42





Why not doing a delegate to dismiss from the VC?

– ironRoei
Nov 19 '18 at 11:42












2 Answers
2






active

oldest

votes


















0














The way you are dismissing a ViewController is not the correct way. The presenting view controller is responsible for dismissing the view controller. Ideally you have to implement a protocol in your presenting ViewController and , dismiss your modal from your 'presenting' ViewController not 'presented' ViewController.



The reason why your way still works is, when a ViewController calls self.dimiss if there's nothing to dismiss UIKit will delegate it back to its parent. If you implement this correct way, once you dismiss , your presenting viewcontroller will dismiss , hence all the presented viewcontrollers will be dismissed instead of the last one.



From Apple Docs:




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.







share|improve this answer























  • I can set a delegate from the initial view controller (which implements the protocol to dismiss) to the first modal with destinationViewController.delegate = self. However, what happens when the first modal calls a second modal? How can I tell the second modal that its delegate will be the initial view controller and not the first modal?

    – cesarcarlos
    Nov 20 '18 at 0:01











  • You don't have to do that. When first modal dismissed by initial VC, all the modals initiated with it and any sub modals initiated after that will be dismissed.

    – sleepwalkerfx
    Nov 20 '18 at 10:55











  • What I don’t understand is, if I’m seing the second modal and I click on a close button, how do I call the initial VC from the second modal?

    – cesarcarlos
    Nov 20 '18 at 11:04











  • @cesarcarlos you just have to pass in the delegate, eg: vc2.deleage = self.delegate in your vc1 when presenting vc2

    – sleepwalkerfx
    Nov 20 '18 at 15:44



















0














try this



 self.navigationController?.viewControllers.removeAll(where: $0.isModalInPopover)





share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53320448%2fdismiss-all-modals-in-ios-with-swift-4%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    The way you are dismissing a ViewController is not the correct way. The presenting view controller is responsible for dismissing the view controller. Ideally you have to implement a protocol in your presenting ViewController and , dismiss your modal from your 'presenting' ViewController not 'presented' ViewController.



    The reason why your way still works is, when a ViewController calls self.dimiss if there's nothing to dismiss UIKit will delegate it back to its parent. If you implement this correct way, once you dismiss , your presenting viewcontroller will dismiss , hence all the presented viewcontrollers will be dismissed instead of the last one.



    From Apple Docs:




    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.







    share|improve this answer























    • I can set a delegate from the initial view controller (which implements the protocol to dismiss) to the first modal with destinationViewController.delegate = self. However, what happens when the first modal calls a second modal? How can I tell the second modal that its delegate will be the initial view controller and not the first modal?

      – cesarcarlos
      Nov 20 '18 at 0:01











    • You don't have to do that. When first modal dismissed by initial VC, all the modals initiated with it and any sub modals initiated after that will be dismissed.

      – sleepwalkerfx
      Nov 20 '18 at 10:55











    • What I don’t understand is, if I’m seing the second modal and I click on a close button, how do I call the initial VC from the second modal?

      – cesarcarlos
      Nov 20 '18 at 11:04











    • @cesarcarlos you just have to pass in the delegate, eg: vc2.deleage = self.delegate in your vc1 when presenting vc2

      – sleepwalkerfx
      Nov 20 '18 at 15:44
















    0














    The way you are dismissing a ViewController is not the correct way. The presenting view controller is responsible for dismissing the view controller. Ideally you have to implement a protocol in your presenting ViewController and , dismiss your modal from your 'presenting' ViewController not 'presented' ViewController.



    The reason why your way still works is, when a ViewController calls self.dimiss if there's nothing to dismiss UIKit will delegate it back to its parent. If you implement this correct way, once you dismiss , your presenting viewcontroller will dismiss , hence all the presented viewcontrollers will be dismissed instead of the last one.



    From Apple Docs:




    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.







    share|improve this answer























    • I can set a delegate from the initial view controller (which implements the protocol to dismiss) to the first modal with destinationViewController.delegate = self. However, what happens when the first modal calls a second modal? How can I tell the second modal that its delegate will be the initial view controller and not the first modal?

      – cesarcarlos
      Nov 20 '18 at 0:01











    • You don't have to do that. When first modal dismissed by initial VC, all the modals initiated with it and any sub modals initiated after that will be dismissed.

      – sleepwalkerfx
      Nov 20 '18 at 10:55











    • What I don’t understand is, if I’m seing the second modal and I click on a close button, how do I call the initial VC from the second modal?

      – cesarcarlos
      Nov 20 '18 at 11:04











    • @cesarcarlos you just have to pass in the delegate, eg: vc2.deleage = self.delegate in your vc1 when presenting vc2

      – sleepwalkerfx
      Nov 20 '18 at 15:44














    0












    0








    0







    The way you are dismissing a ViewController is not the correct way. The presenting view controller is responsible for dismissing the view controller. Ideally you have to implement a protocol in your presenting ViewController and , dismiss your modal from your 'presenting' ViewController not 'presented' ViewController.



    The reason why your way still works is, when a ViewController calls self.dimiss if there's nothing to dismiss UIKit will delegate it back to its parent. If you implement this correct way, once you dismiss , your presenting viewcontroller will dismiss , hence all the presented viewcontrollers will be dismissed instead of the last one.



    From Apple Docs:




    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.







    share|improve this answer













    The way you are dismissing a ViewController is not the correct way. The presenting view controller is responsible for dismissing the view controller. Ideally you have to implement a protocol in your presenting ViewController and , dismiss your modal from your 'presenting' ViewController not 'presented' ViewController.



    The reason why your way still works is, when a ViewController calls self.dimiss if there's nothing to dismiss UIKit will delegate it back to its parent. If you implement this correct way, once you dismiss , your presenting viewcontroller will dismiss , hence all the presented viewcontrollers will be dismissed instead of the last one.



    From Apple Docs:




    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.








    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 19 '18 at 13:58









    sleepwalkerfxsleepwalkerfx

    4,69553352




    4,69553352












    • I can set a delegate from the initial view controller (which implements the protocol to dismiss) to the first modal with destinationViewController.delegate = self. However, what happens when the first modal calls a second modal? How can I tell the second modal that its delegate will be the initial view controller and not the first modal?

      – cesarcarlos
      Nov 20 '18 at 0:01











    • You don't have to do that. When first modal dismissed by initial VC, all the modals initiated with it and any sub modals initiated after that will be dismissed.

      – sleepwalkerfx
      Nov 20 '18 at 10:55











    • What I don’t understand is, if I’m seing the second modal and I click on a close button, how do I call the initial VC from the second modal?

      – cesarcarlos
      Nov 20 '18 at 11:04











    • @cesarcarlos you just have to pass in the delegate, eg: vc2.deleage = self.delegate in your vc1 when presenting vc2

      – sleepwalkerfx
      Nov 20 '18 at 15:44


















    • I can set a delegate from the initial view controller (which implements the protocol to dismiss) to the first modal with destinationViewController.delegate = self. However, what happens when the first modal calls a second modal? How can I tell the second modal that its delegate will be the initial view controller and not the first modal?

      – cesarcarlos
      Nov 20 '18 at 0:01











    • You don't have to do that. When first modal dismissed by initial VC, all the modals initiated with it and any sub modals initiated after that will be dismissed.

      – sleepwalkerfx
      Nov 20 '18 at 10:55











    • What I don’t understand is, if I’m seing the second modal and I click on a close button, how do I call the initial VC from the second modal?

      – cesarcarlos
      Nov 20 '18 at 11:04











    • @cesarcarlos you just have to pass in the delegate, eg: vc2.deleage = self.delegate in your vc1 when presenting vc2

      – sleepwalkerfx
      Nov 20 '18 at 15:44

















    I can set a delegate from the initial view controller (which implements the protocol to dismiss) to the first modal with destinationViewController.delegate = self. However, what happens when the first modal calls a second modal? How can I tell the second modal that its delegate will be the initial view controller and not the first modal?

    – cesarcarlos
    Nov 20 '18 at 0:01





    I can set a delegate from the initial view controller (which implements the protocol to dismiss) to the first modal with destinationViewController.delegate = self. However, what happens when the first modal calls a second modal? How can I tell the second modal that its delegate will be the initial view controller and not the first modal?

    – cesarcarlos
    Nov 20 '18 at 0:01













    You don't have to do that. When first modal dismissed by initial VC, all the modals initiated with it and any sub modals initiated after that will be dismissed.

    – sleepwalkerfx
    Nov 20 '18 at 10:55





    You don't have to do that. When first modal dismissed by initial VC, all the modals initiated with it and any sub modals initiated after that will be dismissed.

    – sleepwalkerfx
    Nov 20 '18 at 10:55













    What I don’t understand is, if I’m seing the second modal and I click on a close button, how do I call the initial VC from the second modal?

    – cesarcarlos
    Nov 20 '18 at 11:04





    What I don’t understand is, if I’m seing the second modal and I click on a close button, how do I call the initial VC from the second modal?

    – cesarcarlos
    Nov 20 '18 at 11:04













    @cesarcarlos you just have to pass in the delegate, eg: vc2.deleage = self.delegate in your vc1 when presenting vc2

    – sleepwalkerfx
    Nov 20 '18 at 15:44






    @cesarcarlos you just have to pass in the delegate, eg: vc2.deleage = self.delegate in your vc1 when presenting vc2

    – sleepwalkerfx
    Nov 20 '18 at 15:44














    0














    try this



     self.navigationController?.viewControllers.removeAll(where: $0.isModalInPopover)





    share|improve this answer



























      0














      try this



       self.navigationController?.viewControllers.removeAll(where: $0.isModalInPopover)





      share|improve this answer

























        0












        0








        0







        try this



         self.navigationController?.viewControllers.removeAll(where: $0.isModalInPopover)





        share|improve this answer













        try this



         self.navigationController?.viewControllers.removeAll(where: $0.isModalInPopover)






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 15 '18 at 13:31









        yildirimatciogluyildirimatcioglu

        126




        126



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53320448%2fdismiss-all-modals-in-ios-with-swift-4%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3

            Museum of Modern and Contemporary Art of Trento and Rovereto