KatanaRouter icon indicating copy to clipboard operation
KatanaRouter copied to clipboard

Update NavigationState due to UIKit Changes?

Open fabb opened this issue 7 years ago • 5 comments

This library looks awesome, but how does it keep track of changes that happen outside of NavigationActions? I.e. when the user uses back swipe or the back button, or he clicks on the currently active tab, which causes the navigation controller to pop to its root view.

I had a similar problem when developing my test project, maybe we can share some thoughts: https://github.com/willhaben/Wireframes

fabb avatar Apr 13 '17 12:04 fabb

Unfortunately there's no easy way.

The "cleanest" solution would be to completely override "Back" button in UINavigationController and create your own interactive transition so you have control over it.

The "easiest" solution is to update it "manually".

I have solved that problem in the KatanaRouterDemo RandomViewController.

        if isMovingFromParentViewController {
            let removeSelf = RemoveDestination(instanceIdentifier: self.instanceIdentifier)
            store.dispatch(removeSelf)
        }

michalciurus avatar Apr 14 '17 08:04 michalciurus

In my project I solved with a workaround involving the UINavigationControllerDelegate: https://github.com/willhaben/Wireframes/blob/master/Source/Wireframes/NavigationControllerWireframe.swift#L105

isMovingFromParentViewController is a good solution, but it needs modification of the ViewControllers, which I wanted to avoid, as I want an easy migration of an existing app.

The "cleanest" solution would be to completely override "Back" button in UINavigationController and create your own interactive transition so you have control over it.

Not really, as for example when you have a UITabBarController, and you press the active tab, it calls popToRootView on the currently active UINavigationController.

fabb avatar Apr 14 '17 09:04 fabb

Yep, you're right.

It's a huge issue, but there's isn't a good way to solve it :( I think I'd go with updating the state manually.

michalciurus avatar Apr 14 '17 10:04 michalciurus

I'm doing a project using a variant of ReSwift and have added routing to it. For the case of the back button (and, in theory, the popToRootView case, although we haven't yet coded for it), we're using the didMove(toParentViewController parentViewController: UIViewController?) call to check for nil, and adjust state manually at that point. When we adjust the state manually we do not notify any subscribers since the view is already updated.

The library I've been hacking on swizzles in support to get lifecycle notifications on another type (we're using coordinators), and we observe it there.

Here's a quick sample for what we're doing in a simple pop off the top of the UINavigationController case: https://github.com/willowtreeapps/cordux/blob/develop-v0.2/Example/CorduxPrototype/AuthenticationCoordinator.swift#L80

All that said, it takes a lot of effort to keep that up to date in all cases. It's been a bit of a headache, especially bringing new developers onto the project.

ianterrell avatar Apr 14 '17 14:04 ianterrell

Excactly, the UINavigationController knows about this stuff internally, but it's not in the public interface, so we have to do wacky workarounds like involving querying its children for information that it already has internally...

fabb avatar Apr 14 '17 14:04 fabb