ReSwift-Router icon indicating copy to clipboard operation
ReSwift-Router copied to clipboard

Routing with UITabBarController scenario

Open dagio opened this issue 7 years ago • 6 comments

UITabBarController allow to have multiple navigation stacks in each tabs. For example :

tabbar

On the previous image we can see tat we have 4 different stacks at the same time :

  • A / Y /
  • B / X /
  • C /
  • D /

The NavigationState design is :

public struct NavigationState {
    public init()
    public var route: Route
    public var routeSpecificState: [ReSwiftRouter.RouteHash : Any]
}

I'm struggling to find a way to use the current implementation while maintaining the native behaviour of the UITabBarController. The idea is to have the following scenario to work properly

Sequence NavigationState.route Next user action
1 / Tab on A in tab bar
2 / A Tap on Y in A
3 / A / Y Tab on B in tab bar
4 / B Tap on A in tab bar
5 / A / Y

Given the current implementation, NavigationState.route in the 5th sequence would be / A instead of / A / Y because the user action in the 4th sequence is destructive.

It seems that we should support non-linear navigation. Maybe more something like a route tree along with the current route in that tree.

dagio avatar Jun 01 '17 14:06 dagio

Interesting. Sounds like you could get past this by having a tab navigation history state where for each root node (A or B, not X or Y) the last active route is stored. Extending NavigationState would be nice, but structs don't provide inheritance, so maybe moving this into a PR once the concept works would be best. It's not a tree state, but it's at least aware of the user's past.

DivineDominion avatar Jun 11 '17 08:06 DivineDominion

Interesting. Sounds like you could get past this by having a tab navigation history state where for each root node (A or B, not X or Y) the last active route is stored.

By "tab navigation history state", you mean a NavigationState for each tab (UIViewController) ?

That would still require some change on the Router to avoid him to ask A to pop Y ?

dagio avatar Jun 18 '17 11:06 dagio

I have an extremely complicated solution for this that is still causing a lot of crashes in an app nearing production due to invalid route states. Basically this is a difficult problem to deal with due to the myriad ways that UIKit navigation can occur that you pretty much have to mirror. Or, I guess you can limit the ways that you interact with UIKit navigation.

My solution consists of a RouterNavigationController and a RouterTabController, a "settled" route state Observable, and some complicated Route logic and traversal that all work together to report user-generated state changes to ReSwift, programmatic state changes that occur without the use of SetRouteAction (e.g. Segues), handling SetRouteActions...

It is truly spaghetti code

jondwillis avatar Aug 17 '17 21:08 jondwillis

@dagio @jondwillis is it possible to make a UITabBarController that supports routing agnostic of the ReSwift-Router? I've started a repo for it, RoutableUIKit, where I thought we might gather UIKit components that supports routing while being agnostic of which routing logic that is being used.

ghost avatar Aug 21 '17 07:08 ghost

I also have the same need to support TabBarController tabs with independent navigation stacks

kdawgwilk avatar Sep 28 '17 17:09 kdawgwilk

We need something very similar, essentially a struct MultiNavigationState that has a different navigation state for every tabbar page that can keep track of everyone of these. Any thoughts on this? How difficult would it be to change ReSwiftRouter to support this?

ciathyza avatar Apr 12 '19 07:04 ciathyza