Coordinator icon indicating copy to clipboard operation
Coordinator copied to clipboard

handlePopBack is not called when 2 coordinators share the same rootViewController

Open krin-san opened this issue 5 years ago • 3 comments

Improvements in 09b040f broke the following use case:

  • App has a single UINavigationController shared between home and account navigation coordinators
  • home coordinator shows the initial screens
  • account coordinator gets control over home.rootViewController when home creates and starts the account on user event (imagine showing an Account screen over the main app screen)
  • User uses the swipe-to-pop to close controller shown by account coordinator

Context before popping:

(lldb) po home.viewControllers
[HomeViewController]

(lldb) po account.viewControllers
[AccountViewController]

(lldb) po navigationController.viewControllers
[HomeViewController, AccountViewController]

When user performs swipe-to-pop gesture, didShowController gets called on account coordinator, but it returns on the check if lastIndex <= index { return } and therefore it:

  • don't remove AccountViewController from viewControllers
  • don't call handlePopBack(to:)
  • don't call parent?.coordinatorDidFinish(...)

krin-san avatar May 15 '19 12:05 krin-san

Test case added in a branch https://github.com/krin-san/Coordinator/tree/bugfix/pop_back_child reproduces this issue.

krin-san avatar May 15 '19 12:05 krin-san

This is nice catch. I'll look into this as soon as I have time.

radianttap avatar May 17 '19 09:05 radianttap

Thinking out-loud...it seems to me in all these cases where I just return from the didShowController(_), I should actually call parent?.coordinatorDidFinish(self, completion: {})

guard let index = viewControllers.firstIndex(of: viewController) else {
	parent?.coordinatorDidFinish(self, completion: {})
	return
}
...
if lastIndex <= index {
	parent?.coordinatorDidFinish(self, completion: {})
	return
}

In the first case, shown VC is not in this Coordinator's domain, thus most likely this Coordinator is not active anymore. In the exit, it's the same thing.

Thus parent Coordinator should then figure out which Coordinator should be re-instated.

radianttap avatar May 19 '19 18:05 radianttap