QuickBirdEng / XCoordinator

🎌 Powerful navigation library for iOS based on the coordinator pattern
MIT License
2.26k stars 177 forks source link

Hometab navigation doesn't seem to work #226

Closed hmcgreevy-instil closed 2 years ago

hmcgreevy-instil commented 2 years ago

I have a setup with an AppCordinator, which holds a TabBarCoordinator with 3 tabs, each tab being it's own coordinator. Everything shows as expected, and we are able to click through the tabs as you'd expect.

However, on the third tab coordinator, we are trying to trigger a navigation back to the first tab, and I can't seem to get the TabBarController to respond to any trigger calls

I've tried this out in your example project as below


init(newsRouter: StrongRouter<NewsRoute>,
         userListRouter: StrongRouter<UserListRoute>) {
        self.newsRouter = newsRouter
        self.userListRouter = userListRouter

        super.init(tabs: [newsRouter, userListRouter], select: userListRouter)

        strongRouter.trigger(.news)
    }

I know that's not the right way to set the initial route, this is just checking to see if it's working, however nothing happens. It doesn't crash or throw any errors, it just doesn't react.

I've also tested the prepareTransition method in this class which also doesn't seem to be doing anything, debug statements are never hit and if I change it to just

override func prepareTransition(for route: HomeRoute) -> TabBarTransition {
            return .select(newsRouter)
        }
    }

It has no impact on behaviour.

Am I missing something around this sort of navigation? The other coordinators all appear to work as expected, just not the tab one

pauljohanneskraft commented 2 years ago

Hey - sorry for the long delay. The tab bar unfortunately does not know about the tabs that you created. While the coordinator can be used to set the tabs programmatically, the coordinator is not used for the user-controlled switching of tabs. This is somewhat a limitation of UIKit's UITabBarController. If you need more control over which tab has been selected, please consider implementing a custom UITabBarControllerDelegate. Please consider setting this delegate on the coordinator's delegate property rather than the view controller directly, since otherwise some animations might not be working as expected.

hmcgreevy-instil commented 2 years ago

Not a problem, thanks for getting back!

Wasn't sure if this was a broken feature, or just not a feature, so thank you for clarifying.

What we ended up doing was something like below (probably not the cleanest approach, but it gets the job done) thank you for the delegate suggestion, I'll take a look at switching over to that.

if let tabController = getUiTabBarController() {
    tabController.selectedViewController = tabController.viewControllers![0]
}

return .dismiss()

private func getUiTabBarController() -> UITabBarController? {
    if let uiViewController = rootViewController.viewControllers.first(where: { $0 is UITabBarController }) {
        return uiViewController as? UITabBarController
    } else {
        return nil
    }
}