marshroute
386 строк · 16.8 Кб
1import Marshroute
2import UIKit
3
4final class MarshrouteFacade {
5// MARK: - Private properties
6let marshrouteStack: MarshrouteStack
7
8// MARK: - Init
9init(marshrouteSetupService: MarshrouteSetupService = MarshrouteSetupServiceImpl()) {
10self.marshrouteStack = marshrouteSetupService.marshrouteStack()
11}
12
13init(marshrouteStack: MarshrouteStack) {
14self.marshrouteStack = marshrouteStack
15}
16
17func navigationModule(
18_ navigationController: UINavigationController? = nil,
19withRootViewControllerDerivedFrom deriveViewController: (RouterSeed) -> (UIViewController))
20-> (UINavigationController, UIViewController, BaseRouter)
21{
22let transitionId = marshrouteStack.transitionIdGenerator.generateNewTransitionId()
23
24let navigationController = navigationController ?? marshrouteStack.routerControllersProvider.navigationController()
25
26let navigationTransitionsHandler = marshrouteStack.transitionsHandlersProvider.navigationTransitionsHandler(
27navigationController: navigationController
28)
29
30let routerSeed = RouterSeed(
31transitionsHandlerBox: .init(animatingTransitionsHandler: navigationTransitionsHandler),
32transitionId: transitionId,
33presentingTransitionsHandler: nil,
34transitionsHandlersProvider: marshrouteStack.transitionsHandlersProvider,
35transitionIdGenerator: marshrouteStack.transitionIdGenerator,
36controllersProvider: marshrouteStack.routerControllersProvider,
37routerTransitionDelegate: nil
38)
39
40let viewController = deriveViewController(routerSeed)
41
42let resetContext = ResettingTransitionContext(
43settingRootViewController: viewController,
44forNavigationController: navigationController,
45navigationTransitionsHandler: navigationTransitionsHandler,
46animator: SetNavigationTransitionsAnimator(),
47transitionId: transitionId
48)
49
50navigationTransitionsHandler.resetWithTransition(
51context: resetContext
52)
53
54return (
55navigationController,
56viewController,
57BaseRouter(routerSeed: routerSeed)
58)
59}
60
61func tabBarController(
62_ tabBarController: (TabBarControllerProtocol & UIViewController)? = nil,
63tabControllerDeriviationFunctionTypes: [TabControllerDeriviationFunctionType])
64-> (TabBarControllerProtocol & UIViewController)
65{
66// MARK: - Preimplementation
67let transitionId = marshrouteStack.transitionIdGenerator.generateNewTransitionId()
68
69// MARK: - Helpers
70func makeRouterSeed(transitionsHandlerBox: TransitionsHandlerBox)
71-> RouterSeed
72{
73return RouterSeed(
74transitionsHandlerBox: transitionsHandlerBox,
75transitionId: transitionId,
76presentingTransitionsHandler: nil,
77transitionsHandlersProvider: marshrouteStack.transitionsHandlersProvider,
78transitionIdGenerator: marshrouteStack.transitionIdGenerator,
79controllersProvider: marshrouteStack.routerControllersProvider,
80routerTransitionDelegate: nil
81)
82}
83
84func deriveDetailController(
85tabIndex: Int,
86detailControllerDeriviationFunctionType: DetailControllerDeriviationFunctionType)
87-> (UIViewController, AnimatingTransitionsHandler)
88{
89switch detailControllerDeriviationFunctionType {
90case .controller(let detailControllerDeriviationFuction):
91return deriveDetailController(
92tabIndex: tabIndex,
93detailControllerDeriviationFuction: detailControllerDeriviationFuction
94)
95
96case .controllerInNavigationController(let detailControllerDeriviationFuction):
97return deriveDetailControllerInNavigationController(
98tabIndex: tabIndex,
99detailControllerDeriviationFuction: detailControllerDeriviationFuction
100)
101}
102}
103
104func deriveDetailController(
105tabIndex: Int,
106detailControllerDeriviationFuction: DetailControllerDeriviationFuction)
107-> (UIViewController, AnimatingTransitionsHandler)
108{
109let animatingTransitionsHandler = marshrouteStack.transitionsHandlersProvider.animatingTransitionsHandler()
110
111let routerSeed = makeRouterSeed(
112transitionsHandlerBox: .init(animatingTransitionsHandler: animatingTransitionsHandler)
113)
114
115let controllerDeriviationParams = DetailControllerDeriviationParams(
116tabIndex: tabIndex,
117routerSeed: routerSeed
118)
119
120let viewController = detailControllerDeriviationFuction.deriveController(controllerDeriviationParams)
121
122let resetContext = ResettingTransitionContext(
123registeringViewController: viewController,
124animatingTransitionsHandler: animatingTransitionsHandler,
125transitionId: transitionId
126)
127
128animatingTransitionsHandler.resetWithTransition(context: resetContext)
129
130return (viewController, animatingTransitionsHandler)
131}
132
133func deriveDetailControllerInNavigationController(
134tabIndex: Int,
135detailControllerDeriviationFuction: DetailControllerDeriviationFuction)
136-> (UIViewController, AnimatingTransitionsHandler)
137{
138let navigationController = marshrouteStack.routerControllersProvider.navigationController()
139
140let navigationTransitionsHandler = marshrouteStack.transitionsHandlersProvider.navigationTransitionsHandler(
141navigationController: navigationController
142)
143
144let routerSeed = makeRouterSeed(
145transitionsHandlerBox: .init(animatingTransitionsHandler: navigationTransitionsHandler)
146)
147
148let controllerDeriviationParams = DetailControllerDeriviationParams(
149tabIndex: tabIndex,
150routerSeed: routerSeed
151)
152
153let viewController = detailControllerDeriviationFuction.deriveController(controllerDeriviationParams)
154
155let resetContext = ResettingTransitionContext(
156settingRootViewController: viewController,
157forNavigationController: navigationController,
158navigationTransitionsHandler: navigationTransitionsHandler,
159animator: SetNavigationTransitionsAnimator(),
160transitionId: transitionId
161)
162
163navigationTransitionsHandler.resetWithTransition(
164context: resetContext
165)
166
167return (viewController, navigationTransitionsHandler)
168}
169
170// MARK: - MasterDetail helpers
171
172func makeMasterDetailRouterSeed(
173masterTransitionsHandlerBox: TransitionsHandlerBox,
174detailTransitionsHandlerBox: TransitionsHandlerBox)
175-> MasterDetailRouterSeed
176{
177return MasterDetailRouterSeed(
178masterTransitionsHandlerBox: masterTransitionsHandlerBox,
179detailTransitionsHandlerBox: detailTransitionsHandlerBox,
180transitionId: transitionId,
181presentingTransitionsHandler: nil,
182transitionsHandlersProvider: marshrouteStack.transitionsHandlersProvider,
183transitionIdGenerator: marshrouteStack.transitionIdGenerator,
184controllersProvider: marshrouteStack.routerControllersProvider,
185routerTransitionDelegate: nil
186)
187}
188
189func deriveMasterController(
190tabIndex: Int,
191detailTransitionsHandlerBox: TransitionsHandlerBox,
192masterControllerDeriviationFunctionType: MasterControllerDeriviationFunctionType)
193-> (UIViewController, AnimatingTransitionsHandler)
194{
195switch masterControllerDeriviationFunctionType {
196case .controller(let masterControllerDeriviationFuction):
197return deriveMasterController(
198tabIndex: tabIndex,
199detailTransitionsHandlerBox: detailTransitionsHandlerBox,
200masterControllerDeriviationFuction: masterControllerDeriviationFuction
201)
202
203case .controllerInNavigationController(let masterControllerDeriviationFuction):
204return deriveMasterControllerInNavigationController(
205tabIndex: tabIndex,
206detailTransitionsHandlerBox: detailTransitionsHandlerBox,
207masterControllerDeriviationFuction: masterControllerDeriviationFuction
208)
209}
210}
211
212func deriveMasterController(
213tabIndex: Int,
214detailTransitionsHandlerBox: TransitionsHandlerBox,
215masterControllerDeriviationFuction: MasterControllerDeriviationFunction)
216-> (UIViewController, AnimatingTransitionsHandler)
217{
218let animatingTransitionsHandler = marshrouteStack.transitionsHandlersProvider.animatingTransitionsHandler()
219
220let routerSeed = makeMasterDetailRouterSeed(
221masterTransitionsHandlerBox: .init(animatingTransitionsHandler: animatingTransitionsHandler),
222detailTransitionsHandlerBox: detailTransitionsHandlerBox
223)
224
225let controllerDeriviationParams = MasterControllerDeriviationParams(
226tabIndex: tabIndex,
227routerSeed: routerSeed
228)
229
230let viewController = masterControllerDeriviationFuction.deriveController(controllerDeriviationParams)
231
232let resetContext = ResettingTransitionContext(
233registeringViewController: viewController,
234animatingTransitionsHandler: animatingTransitionsHandler,
235transitionId: transitionId
236)
237
238animatingTransitionsHandler.resetWithTransition(context: resetContext)
239
240return (viewController, animatingTransitionsHandler)
241}
242
243func deriveMasterControllerInNavigationController(
244tabIndex: Int,
245detailTransitionsHandlerBox: TransitionsHandlerBox,
246masterControllerDeriviationFuction: MasterControllerDeriviationFunction)
247-> (UIViewController, AnimatingTransitionsHandler)
248{
249let navigationController = marshrouteStack.routerControllersProvider.navigationController()
250
251let navigationTransitionsHandler = marshrouteStack.transitionsHandlersProvider.navigationTransitionsHandler(
252navigationController: navigationController
253)
254
255let routerSeed = makeMasterDetailRouterSeed(
256masterTransitionsHandlerBox: .init(animatingTransitionsHandler: navigationTransitionsHandler),
257detailTransitionsHandlerBox: detailTransitionsHandlerBox
258)
259
260let controllerDeriviationParams = MasterControllerDeriviationParams(
261tabIndex: tabIndex,
262routerSeed: routerSeed
263)
264
265let viewController = masterControllerDeriviationFuction.deriveController(controllerDeriviationParams)
266
267let resetContext = ResettingTransitionContext(
268settingRootViewController: viewController,
269forNavigationController: navigationController,
270navigationTransitionsHandler: navigationTransitionsHandler,
271animator: SetNavigationTransitionsAnimator(),
272transitionId: transitionId
273)
274
275navigationTransitionsHandler.resetWithTransition(
276context: resetContext
277)
278
279return (viewController, navigationTransitionsHandler)
280}
281
282func deriveMasterDetailController(
283tabIndex: Int,
284masterDetailControllerDeriviationFuctionTypes: MasterDetailControllerDeriviationFuctionTypes)
285-> (SplitViewControllerProtocol & UIViewController, SplitViewTransitionsHandler)
286{
287let (detailController, detaillTransitionHandler) = deriveDetailController(
288tabIndex: tabIndex,
289detailControllerDeriviationFunctionType: masterDetailControllerDeriviationFuctionTypes.detailFunctionType
290)
291
292let (masterController, masterTransitionsHandler) = deriveMasterController(
293tabIndex: tabIndex,
294detailTransitionsHandlerBox: .init(animatingTransitionsHandler: detaillTransitionHandler),
295masterControllerDeriviationFunctionType: masterDetailControllerDeriviationFuctionTypes.masterFunctionType
296)
297
298let splitViewController = marshrouteStack.routerControllersProvider.splitViewController()
299
300splitViewController.viewControllers = [masterController, detailController]
301
302let splitTransitionsHandler = marshrouteStack.transitionsHandlersProvider.splitViewTransitionsHandler(
303splitViewController: splitViewController
304)
305
306splitTransitionsHandler.masterTransitionsHandler = masterTransitionsHandler
307splitTransitionsHandler.detailTransitionsHandler = detaillTransitionHandler
308
309return (splitViewController, splitTransitionsHandler)
310}
311
312// MARK: - Implementation
313let tabBarController = tabBarController ?? UITabBarController()
314
315let tabTransitionsHandler = marshrouteStack.transitionsHandlersProvider.tabBarTransitionsHandler(
316tabBarController: tabBarController
317)
318
319var animatingTransitionsHandlers = [Int: AnimatingTransitionsHandler]()
320var containingTransitionsHandlers = [Int: ContainingTransitionsHandler]()
321var tabControllers = [UIViewController]()
322
323for (tabIndex, deriviationFunctionType) in tabControllerDeriviationFunctionTypes.enumerated() {
324switch deriviationFunctionType {
325case .controller(let detailControllerDeriviationFunctionType):
326let (viewController, animatingTransitionsHandler) = deriveDetailController(
327tabIndex: tabIndex,
328detailControllerDeriviationFunctionType: detailControllerDeriviationFunctionType
329)
330tabControllers.append(viewController)
331animatingTransitionsHandlers[tabIndex] = animatingTransitionsHandler
332
333case .masterDetailController(let masterDetailControllerDeriviationFuctionTypes):
334let (viewController, containingTransitionsHandler) = deriveMasterDetailController(
335tabIndex: tabIndex,
336masterDetailControllerDeriviationFuctionTypes: masterDetailControllerDeriviationFuctionTypes
337)
338tabControllers.append(viewController)
339containingTransitionsHandlers[tabIndex] = containingTransitionsHandler
340}
341}
342
343tabTransitionsHandler.animatingTransitionsHandlers = animatingTransitionsHandlers
344tabTransitionsHandler.containingTransitionsHandlers = containingTransitionsHandlers
345
346return tabBarController
347}
348}
349
350struct DetailControllerDeriviationParams {
351let tabIndex: Int
352let routerSeed: RouterSeed
353}
354
355struct DetailControllerDeriviationFuction {
356let deriveController: ((DetailControllerDeriviationParams) -> (UIViewController))
357}
358
359enum DetailControllerDeriviationFunctionType {
360case controller(DetailControllerDeriviationFuction)
361case controllerInNavigationController(DetailControllerDeriviationFuction)
362}
363
364struct MasterControllerDeriviationParams {
365let tabIndex: Int
366let routerSeed: MasterDetailRouterSeed
367}
368
369struct MasterControllerDeriviationFunction {
370let deriveController: ((MasterControllerDeriviationParams) -> (UIViewController))
371}
372
373enum MasterControllerDeriviationFunctionType {
374case controller(MasterControllerDeriviationFunction)
375case controllerInNavigationController(MasterControllerDeriviationFunction)
376}
377
378struct MasterDetailControllerDeriviationFuctionTypes {
379let masterFunctionType: MasterControllerDeriviationFunctionType
380let detailFunctionType: DetailControllerDeriviationFunctionType
381}
382
383enum TabControllerDeriviationFunctionType {
384case controller(DetailControllerDeriviationFunctionType)
385case masterDetailController(MasterDetailControllerDeriviationFuctionTypes)
386}
387