viewDidLoad called twice, using navigation controller











up vote
0
down vote

favorite












My ViewDidLoad method on a ViewController is called twice, but only in a particular scenario. There are two view controllers which I need to present, one if user isn't logged in and the second if the user is logged in. I am using storyboard and have set a navigation controller as initial view controller in it.



In my AppDelegate didFinishLaunchingWithOptions method I have populated ViewControllers array with the desired controller as below



let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateViewController(withIdentifier: "navController") as! UINavigationController
if UserDefaults.standard.object(forKey: USERID) != nil {
viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
}
else {
viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
}
navigationController.viewControllers = [viewController] as! [UIViewController]
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()


ViewDidLoad method in HomeVC is called twice, whereas it's called just once for LoginVC.



I already tried searching through articles viewDidLoad is called twice and viewDidLoad getting called twice on rootViewController at launch but couldn't corner the issue.










share|improve this question




















  • 1




    I think this is due to segue in Storyboard.
    – Rizwan
    Nov 19 at 8:11










  • I have ticked "Is Initial View Controller" for navigation controller. No other segue used. If I remove it, it shows a black screen on loading.
    – Sam
    Nov 19 at 8:16












  • if you setting root view controller programmatically then remove main interface from Deployment Info.
    – Jatin Kathrotiya
    Nov 19 at 8:20










  • Maybe the UITabViewController is better for your UI design. You can hide tab button and control it by codes.
    – AechoLiu
    Nov 19 at 9:28










  • @JatinKathrotiya Removing "Main Storyboard file base name" presents a black screen after splash.
    – Sam
    Nov 19 at 10:00















up vote
0
down vote

favorite












My ViewDidLoad method on a ViewController is called twice, but only in a particular scenario. There are two view controllers which I need to present, one if user isn't logged in and the second if the user is logged in. I am using storyboard and have set a navigation controller as initial view controller in it.



In my AppDelegate didFinishLaunchingWithOptions method I have populated ViewControllers array with the desired controller as below



let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateViewController(withIdentifier: "navController") as! UINavigationController
if UserDefaults.standard.object(forKey: USERID) != nil {
viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
}
else {
viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
}
navigationController.viewControllers = [viewController] as! [UIViewController]
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()


ViewDidLoad method in HomeVC is called twice, whereas it's called just once for LoginVC.



I already tried searching through articles viewDidLoad is called twice and viewDidLoad getting called twice on rootViewController at launch but couldn't corner the issue.










share|improve this question




















  • 1




    I think this is due to segue in Storyboard.
    – Rizwan
    Nov 19 at 8:11










  • I have ticked "Is Initial View Controller" for navigation controller. No other segue used. If I remove it, it shows a black screen on loading.
    – Sam
    Nov 19 at 8:16












  • if you setting root view controller programmatically then remove main interface from Deployment Info.
    – Jatin Kathrotiya
    Nov 19 at 8:20










  • Maybe the UITabViewController is better for your UI design. You can hide tab button and control it by codes.
    – AechoLiu
    Nov 19 at 9:28










  • @JatinKathrotiya Removing "Main Storyboard file base name" presents a black screen after splash.
    – Sam
    Nov 19 at 10:00













up vote
0
down vote

favorite









up vote
0
down vote

favorite











My ViewDidLoad method on a ViewController is called twice, but only in a particular scenario. There are two view controllers which I need to present, one if user isn't logged in and the second if the user is logged in. I am using storyboard and have set a navigation controller as initial view controller in it.



In my AppDelegate didFinishLaunchingWithOptions method I have populated ViewControllers array with the desired controller as below



let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateViewController(withIdentifier: "navController") as! UINavigationController
if UserDefaults.standard.object(forKey: USERID) != nil {
viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
}
else {
viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
}
navigationController.viewControllers = [viewController] as! [UIViewController]
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()


ViewDidLoad method in HomeVC is called twice, whereas it's called just once for LoginVC.



I already tried searching through articles viewDidLoad is called twice and viewDidLoad getting called twice on rootViewController at launch but couldn't corner the issue.










share|improve this question















My ViewDidLoad method on a ViewController is called twice, but only in a particular scenario. There are two view controllers which I need to present, one if user isn't logged in and the second if the user is logged in. I am using storyboard and have set a navigation controller as initial view controller in it.



In my AppDelegate didFinishLaunchingWithOptions method I have populated ViewControllers array with the desired controller as below



let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateViewController(withIdentifier: "navController") as! UINavigationController
if UserDefaults.standard.object(forKey: USERID) != nil {
viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
}
else {
viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
}
navigationController.viewControllers = [viewController] as! [UIViewController]
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()


ViewDidLoad method in HomeVC is called twice, whereas it's called just once for LoginVC.



I already tried searching through articles viewDidLoad is called twice and viewDidLoad getting called twice on rootViewController at launch but couldn't corner the issue.







ios swift uinavigationcontroller rootviewcontroller






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 at 9:38









Denis

38814




38814










asked Nov 19 at 8:02









Sam

131317




131317








  • 1




    I think this is due to segue in Storyboard.
    – Rizwan
    Nov 19 at 8:11










  • I have ticked "Is Initial View Controller" for navigation controller. No other segue used. If I remove it, it shows a black screen on loading.
    – Sam
    Nov 19 at 8:16












  • if you setting root view controller programmatically then remove main interface from Deployment Info.
    – Jatin Kathrotiya
    Nov 19 at 8:20










  • Maybe the UITabViewController is better for your UI design. You can hide tab button and control it by codes.
    – AechoLiu
    Nov 19 at 9:28










  • @JatinKathrotiya Removing "Main Storyboard file base name" presents a black screen after splash.
    – Sam
    Nov 19 at 10:00














  • 1




    I think this is due to segue in Storyboard.
    – Rizwan
    Nov 19 at 8:11










  • I have ticked "Is Initial View Controller" for navigation controller. No other segue used. If I remove it, it shows a black screen on loading.
    – Sam
    Nov 19 at 8:16












  • if you setting root view controller programmatically then remove main interface from Deployment Info.
    – Jatin Kathrotiya
    Nov 19 at 8:20










  • Maybe the UITabViewController is better for your UI design. You can hide tab button and control it by codes.
    – AechoLiu
    Nov 19 at 9:28










  • @JatinKathrotiya Removing "Main Storyboard file base name" presents a black screen after splash.
    – Sam
    Nov 19 at 10:00








1




1




I think this is due to segue in Storyboard.
– Rizwan
Nov 19 at 8:11




I think this is due to segue in Storyboard.
– Rizwan
Nov 19 at 8:11












I have ticked "Is Initial View Controller" for navigation controller. No other segue used. If I remove it, it shows a black screen on loading.
– Sam
Nov 19 at 8:16






I have ticked "Is Initial View Controller" for navigation controller. No other segue used. If I remove it, it shows a black screen on loading.
– Sam
Nov 19 at 8:16














if you setting root view controller programmatically then remove main interface from Deployment Info.
– Jatin Kathrotiya
Nov 19 at 8:20




if you setting root view controller programmatically then remove main interface from Deployment Info.
– Jatin Kathrotiya
Nov 19 at 8:20












Maybe the UITabViewController is better for your UI design. You can hide tab button and control it by codes.
– AechoLiu
Nov 19 at 9:28




Maybe the UITabViewController is better for your UI design. You can hide tab button and control it by codes.
– AechoLiu
Nov 19 at 9:28












@JatinKathrotiya Removing "Main Storyboard file base name" presents a black screen after splash.
– Sam
Nov 19 at 10:00




@JatinKathrotiya Removing "Main Storyboard file base name" presents a black screen after splash.
– Sam
Nov 19 at 10:00












2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










When you create your navigation view controller from the storyboard, this already contains it's rootViewController (which must not to be confused with the rootViewController of the UIWindow). I guess this is your HomeVC (in the storyboard). So, the storyboard magic already creates HomeVC, and you do not have to create it manually in didFinishLaunchingWithOptions.



If you have specify the storyboard as your main interface in the project's/target's properties, you do not need any creational code in didFinishLaunchingWithOptions and just let the framework perform the magic.



If you want to do this programatically, then - in the storyboard - you should remove the navigation controller, and create it manually (not via instantiateViewController) in didFinishLaunchingWithOptions. You would also add the appropriate root view controller here (instantiated from the storyboard), maybe like this:



let storyboard = UIStoryboard(name: "Main", bundle: nil)

if UserDefaults.standard.object(forKey: USERID) != nil {
viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
} else {
viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
}
let navigationController = UINavigationController(rootViewController:viewController)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()





share|improve this answer























  • thanks. I removed navigation controller from storyboard and created the same manually, but the issue still repeats. On auto-login when control directly goes to the HomeVC, viewDidLoad is called just once, as desired. But in case of first time login, when it navigates from LoginVC, then its called twice.
    – Sam
    Nov 19 at 11:07


















up vote
0
down vote













I would recommend don't do any manual segue OR load view controller in app delegate. Use following piece of code in viewDidLoad of LoginView (hoping this is root view of your app always).



Use segue for login to homeview.



if UserDefaults.standard.object(forKey: USERID) != nil {
self.performSegue(withIdentifier: "HomeViewIdentifier", sender: self)
}


Considering HomeViewIdentifier is a segueId for LoginView to HomeView.
Why I am suggesting this because you need to segue back to loginView when user logs out. In case you make homeView as rootview then where will you go in case of logout.






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',
    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%2f53370504%2fviewdidload-called-twice-using-navigation-controller%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








    up vote
    2
    down vote



    accepted










    When you create your navigation view controller from the storyboard, this already contains it's rootViewController (which must not to be confused with the rootViewController of the UIWindow). I guess this is your HomeVC (in the storyboard). So, the storyboard magic already creates HomeVC, and you do not have to create it manually in didFinishLaunchingWithOptions.



    If you have specify the storyboard as your main interface in the project's/target's properties, you do not need any creational code in didFinishLaunchingWithOptions and just let the framework perform the magic.



    If you want to do this programatically, then - in the storyboard - you should remove the navigation controller, and create it manually (not via instantiateViewController) in didFinishLaunchingWithOptions. You would also add the appropriate root view controller here (instantiated from the storyboard), maybe like this:



    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    if UserDefaults.standard.object(forKey: USERID) != nil {
    viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
    } else {
    viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
    }
    let navigationController = UINavigationController(rootViewController:viewController)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()





    share|improve this answer























    • thanks. I removed navigation controller from storyboard and created the same manually, but the issue still repeats. On auto-login when control directly goes to the HomeVC, viewDidLoad is called just once, as desired. But in case of first time login, when it navigates from LoginVC, then its called twice.
      – Sam
      Nov 19 at 11:07















    up vote
    2
    down vote



    accepted










    When you create your navigation view controller from the storyboard, this already contains it's rootViewController (which must not to be confused with the rootViewController of the UIWindow). I guess this is your HomeVC (in the storyboard). So, the storyboard magic already creates HomeVC, and you do not have to create it manually in didFinishLaunchingWithOptions.



    If you have specify the storyboard as your main interface in the project's/target's properties, you do not need any creational code in didFinishLaunchingWithOptions and just let the framework perform the magic.



    If you want to do this programatically, then - in the storyboard - you should remove the navigation controller, and create it manually (not via instantiateViewController) in didFinishLaunchingWithOptions. You would also add the appropriate root view controller here (instantiated from the storyboard), maybe like this:



    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    if UserDefaults.standard.object(forKey: USERID) != nil {
    viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
    } else {
    viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
    }
    let navigationController = UINavigationController(rootViewController:viewController)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()





    share|improve this answer























    • thanks. I removed navigation controller from storyboard and created the same manually, but the issue still repeats. On auto-login when control directly goes to the HomeVC, viewDidLoad is called just once, as desired. But in case of first time login, when it navigates from LoginVC, then its called twice.
      – Sam
      Nov 19 at 11:07













    up vote
    2
    down vote



    accepted







    up vote
    2
    down vote



    accepted






    When you create your navigation view controller from the storyboard, this already contains it's rootViewController (which must not to be confused with the rootViewController of the UIWindow). I guess this is your HomeVC (in the storyboard). So, the storyboard magic already creates HomeVC, and you do not have to create it manually in didFinishLaunchingWithOptions.



    If you have specify the storyboard as your main interface in the project's/target's properties, you do not need any creational code in didFinishLaunchingWithOptions and just let the framework perform the magic.



    If you want to do this programatically, then - in the storyboard - you should remove the navigation controller, and create it manually (not via instantiateViewController) in didFinishLaunchingWithOptions. You would also add the appropriate root view controller here (instantiated from the storyboard), maybe like this:



    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    if UserDefaults.standard.object(forKey: USERID) != nil {
    viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
    } else {
    viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
    }
    let navigationController = UINavigationController(rootViewController:viewController)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()





    share|improve this answer














    When you create your navigation view controller from the storyboard, this already contains it's rootViewController (which must not to be confused with the rootViewController of the UIWindow). I guess this is your HomeVC (in the storyboard). So, the storyboard magic already creates HomeVC, and you do not have to create it manually in didFinishLaunchingWithOptions.



    If you have specify the storyboard as your main interface in the project's/target's properties, you do not need any creational code in didFinishLaunchingWithOptions and just let the framework perform the magic.



    If you want to do this programatically, then - in the storyboard - you should remove the navigation controller, and create it manually (not via instantiateViewController) in didFinishLaunchingWithOptions. You would also add the appropriate root view controller here (instantiated from the storyboard), maybe like this:



    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    if UserDefaults.standard.object(forKey: USERID) != nil {
    viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
    } else {
    viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
    }
    let navigationController = UINavigationController(rootViewController:viewController)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 19 at 8:28

























    answered Nov 19 at 8:21









    Andreas Oetjen

    3,89111125




    3,89111125












    • thanks. I removed navigation controller from storyboard and created the same manually, but the issue still repeats. On auto-login when control directly goes to the HomeVC, viewDidLoad is called just once, as desired. But in case of first time login, when it navigates from LoginVC, then its called twice.
      – Sam
      Nov 19 at 11:07


















    • thanks. I removed navigation controller from storyboard and created the same manually, but the issue still repeats. On auto-login when control directly goes to the HomeVC, viewDidLoad is called just once, as desired. But in case of first time login, when it navigates from LoginVC, then its called twice.
      – Sam
      Nov 19 at 11:07
















    thanks. I removed navigation controller from storyboard and created the same manually, but the issue still repeats. On auto-login when control directly goes to the HomeVC, viewDidLoad is called just once, as desired. But in case of first time login, when it navigates from LoginVC, then its called twice.
    – Sam
    Nov 19 at 11:07




    thanks. I removed navigation controller from storyboard and created the same manually, but the issue still repeats. On auto-login when control directly goes to the HomeVC, viewDidLoad is called just once, as desired. But in case of first time login, when it navigates from LoginVC, then its called twice.
    – Sam
    Nov 19 at 11:07












    up vote
    0
    down vote













    I would recommend don't do any manual segue OR load view controller in app delegate. Use following piece of code in viewDidLoad of LoginView (hoping this is root view of your app always).



    Use segue for login to homeview.



    if UserDefaults.standard.object(forKey: USERID) != nil {
    self.performSegue(withIdentifier: "HomeViewIdentifier", sender: self)
    }


    Considering HomeViewIdentifier is a segueId for LoginView to HomeView.
    Why I am suggesting this because you need to segue back to loginView when user logs out. In case you make homeView as rootview then where will you go in case of logout.






    share|improve this answer



























      up vote
      0
      down vote













      I would recommend don't do any manual segue OR load view controller in app delegate. Use following piece of code in viewDidLoad of LoginView (hoping this is root view of your app always).



      Use segue for login to homeview.



      if UserDefaults.standard.object(forKey: USERID) != nil {
      self.performSegue(withIdentifier: "HomeViewIdentifier", sender: self)
      }


      Considering HomeViewIdentifier is a segueId for LoginView to HomeView.
      Why I am suggesting this because you need to segue back to loginView when user logs out. In case you make homeView as rootview then where will you go in case of logout.






      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        I would recommend don't do any manual segue OR load view controller in app delegate. Use following piece of code in viewDidLoad of LoginView (hoping this is root view of your app always).



        Use segue for login to homeview.



        if UserDefaults.standard.object(forKey: USERID) != nil {
        self.performSegue(withIdentifier: "HomeViewIdentifier", sender: self)
        }


        Considering HomeViewIdentifier is a segueId for LoginView to HomeView.
        Why I am suggesting this because you need to segue back to loginView when user logs out. In case you make homeView as rootview then where will you go in case of logout.






        share|improve this answer














        I would recommend don't do any manual segue OR load view controller in app delegate. Use following piece of code in viewDidLoad of LoginView (hoping this is root view of your app always).



        Use segue for login to homeview.



        if UserDefaults.standard.object(forKey: USERID) != nil {
        self.performSegue(withIdentifier: "HomeViewIdentifier", sender: self)
        }


        Considering HomeViewIdentifier is a segueId for LoginView to HomeView.
        Why I am suggesting this because you need to segue back to loginView when user logs out. In case you make homeView as rootview then where will you go in case of logout.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 19 at 8:31

























        answered Nov 19 at 8:26









        Rizwan

        1,240418




        1,240418






























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53370504%2fviewdidload-called-twice-using-navigation-controller%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







            Popular posts from this blog

            "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

            Alcedinidae

            Origin of the phrase “under your belt”?