QuickBirdEng / XCoordinator

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

How implemented the PageCoordinator ? #77

Closed tsomaev closed 5 years ago

tsomaev commented 5 years ago

I have the root coordinator, HomeTabCoordinator, and this router I set two tabbar items, AboutController and NewsController and created for them coordinate classes.

For NewsCoordinator I have next router:

enum NewsListRouter: Route {
    case newsList
    case selectedNews(newsID: Int)
}

and I open the NewsDetailViewController next way:

func detailNewsTrigger(_ id: Int) {
        router.trigger(.selectedNews(newsID: id))
    }

For this screen I have the next design, buttons for news paging:

Screenshot 2019-03-24 at 01 54 31

How do I implement the function, when tapped for NextButton, showing next news and also, the previewButton, showing preview news ?

I know about the PageCoordinator, but no idea how it implemented for my project, although looking at your example HomePageCoordinator. Please, help

pauljohanneskraft commented 5 years ago

PageCoordinator seems to be an interesting idea here, although I'd say it would require a custom UIPageViewControllerDataSource in which the next or previous view controllers are loaded (at least, if lazy loading is required, which it probably should).

I'm ignoring data flow for now, since I don't know how the existing project is set up and there are like a million possible ways.

For changing the currently displayed page from the tap of a button use PageTransition.set(_:direction:) with the to-be-shown viewController(s) and the direction in which the animation should be shown (just like UIPageViewController.setViewControllers).

If swiping is required/wanted, use the UIPageViewControllerDataSource methods in your delegate that you are providing in the initializer to generate viewControllers depending on the swipe direction. (If you are overriding generateRootViewController this dataSource might not be set though).

pauljohanneskraft commented 5 years ago

For a route type with cases left and right, the following code illustrates a way, where one would only need to implement a UIPageViewControllerDataSource and connect the buttons to the respective route cases.

case .left:
    guard let currentViewController = rootViewController.viewControllers?.first,
        let previousViewController = rootViewController.dataSource?
            .pageViewController(rootViewController, viewControllerBefore: currentViewController) else {
                return .none()
    }
    return .set(previousViewController, direction: .reverse)
case .right:
    guard let currentViewController = rootViewController.viewControllers?.first,
        let nextViewController = rootViewController.dataSource?
            .pageViewController(rootViewController, viewControllerAfter: currentViewController) else {
                return .none()
    }
    return .set(nextViewController, direction: .forward)
pauljohanneskraft commented 5 years ago

I'm closing this now - if the question / problem persists or there are follow-up questions, feel free to reopen.

tsomaev commented 5 years ago

thanks for the answer!

tsomaev commented 5 years ago

@pauljohanneskraft, I need implement a PageCoordinatorDataSource ? And if so, how I create controller and use the pages stored properties ?

tsomaev commented 5 years ago

It would be cool to see an example with a similar implementation that I brought

pauljohanneskraft commented 5 years ago

With the most recent version of XCoordinator, you can also create a PageCoordinator without being constrained to the PageCoordinatorDataSource, but you can instead use any UIPageViewControllerDataSource.

For an example of a PageCoordinator with a PageCoordinatorDataSource, please take a look at the HomePageCoordinator in the Example app. Also take a look at the source of PageCoordinatorDataSource for an implementation of a UIPageViewControllerDataSource. There are also a couple of examples on how to trigger routes as a result of a button tap in the Example app.

If there are further questions, please elaborate a bit further on the challenges you are facing.

pauljohanneskraft commented 5 years ago

In UIPageViewControllerDataSource there is no stored property pages, this is only the case for our implementation PageControllerDataSource.

Please refer to the UIKit documentation for further questions regarding the UIPageViewControllerDataSource protocol.

If you have further questions regarding the XCoordinator framework, feel free to ask, but please keep in mind, that without elaborating on your problem, it is really hard to understand the problem and as a result of that, it is hard to find a solution.