After clicking the back to Checklist app goes make the Checklist Item

After I add a few items and click to go back to the List view. The checklist view show then jumps to the checklist item view. I’m not sure what is going on here.

Here is a link to my code: https://drive.google.com/file/d/1WNX4NsdXE3OBFPSvYh9KxYE7U6dN40rA/view?usp=sharing

The source for your AllListsViewController.swift combines the code from both the viewWillAppear and viewDidAppear methods in the book into viewWillAppear. The reason the code is separated is because viewWillAppear and viewDidAppear are not equivalent - there’s a timing difference as to when each method fires :slight_smile: If you separate out the code as in the book, the issue you’re seeing will go away …

1 Like

Thanks. I cannot believe I overlooked that.

So the methods are called in this order?

  1. viewWillAppear
  2. viewDidAppear
  3. viewDidLoad

No :slight_smile: viewDidLoad gets called first and it gets called only once - when the view controller is first initialized.

Both viewWillAppear and viewDidAppear can get called multiple times (and in that order). For example, when the view controller is first shown, both will get called. Then, if you navigate to a new view and then come back, they get called again.

Thanks. I got it now.

I don’t think viewDidLoad() is relevant to what you were seeing in your code. I think the issue is: when does the method navigationController(willShow:animated:) execute relative to viewWillAppear() and viewDidAppear()? The method navigationController(willShow:animated:) is what sets the dataModel.indexOfSelectedCheckList flag to -1, and if that flag is set to -1 then performSegue(withIdentifier: "ShowChecklist", sender:) is skipped, which means you won’t get bounced back to the ChecklistViewController.

Because of the “bounce back” you are seeing when you put the -1 check in viewWillAppear(), you can use some simple logic to suss out the order of execution of the methods:

  • navigationController(willShow:animated:)
  • viewWillAppear()
  • viewDidAppear()

If navigationController(willShow:animated:) executed before viewWillAppear() and viewDidAppear(), then the flag would get set to -1 by the time either of them executed, and therefore it wouldn’t matter which of viewWillAppear() or viewDidAppear() contained the check for the -1 flag. In either case, the flag would be -1, so performSegue(withIdentifier: "ShowChecklist", sender:) would be skipped, and you wouldn’t see your app bounce back to the ChecklistViewController. That means navigationController(willShow:animated:) cannot execute first.

Similarly, if navigationController(willShow:animated:) executed last then the dataModel.indexOfSelectedCheckList flag would never get set to -1 before viewWillAppear() or viewDidAppear() executed, which would mean that no matter which of viewWillAppear() or viewDidAppear() contained the check for the -1 flag, it would always be false, so you would bounce back to the ChecklistViewController no matter which method contained the -1 check–but we know from your results that that isn’t the case: if you put the check for the -1 flag in viewWillAppear() you see the bounce back, and if you put the check for the -1 flag in viewDidAppear(), there is no bounce back to the ChecklistViewController. Therefore, navigationController(willShow:animated:) cannot execute last.

If navigationController(willShow:animated:) cannot execute first, and it cannot execute last, then navigationController(willShow:animated:) has to execute second.

Now, which of viewWillAppear() and viewDidAppear() executes first? 1) The method names indicate which executes first. 2) Because you got the bounce back effect when checking for -1 in viewWillAppear(), the flag is never -1 in viewWillAppear(), therefore performSegue(identifier: "ShowChecklist", sender:) sends you back to the ChecklistViewController. That means that viewWillAppear() must execute before navigationController(willShow:animated:) has a chance to set the flag to -1, which means that viewWillAppear() must execute first. That leaves last place for viewDidAppear(), which is also confirmed by correcting your code and placing the -1 check in viewDidAppear(): the flag gets set to -1, so performSegue(identifier: "ShowChecklist", sender:) is skipped and no bounce back to the ChecklistViewController.

As a result, the order of execution must be:

  1. viewWillAppear() → (-1 flag has not been set yet.)
  2. navigationController(willShow:animated:) → (Sets -1 flag.)
  3. viewDidAppear() → (-1 flag is set.)
1 Like

This topic was automatically closed after 166 days. New replies are no longer allowed.