/* Copyright 2019-2024 New Vector Ltd. SPDX-License-Identifier: AGPL-3.0-only Please see LICENSE in the repository root for full details. */ import UIKit /// Protocol describing a router that wraps a UINavigationController and add convenient completion handlers. Completions are called when a Presentable is removed. /// Routers are used to be passed between coordinators. They handles only `physical` navigation. protocol NavigationRouterType: AnyObject, Presentable { /// Present modally a view controller on the navigation controller /// /// - Parameter module: The Presentable to present. /// - Parameter animated: Specify true to animate the transition. func present(_ module: Presentable, animated: Bool) /// Dismiss presented view controller from navigation controller /// /// - Parameter animated: Specify true to animate the transition. /// - Parameter completion: Animation completion (not the pop completion). func dismissModule(animated: Bool, completion: (() -> Void)?) /// Set root view controller of navigation controller /// /// - Parameter module: The Presentable to set as root. /// - Parameter hideNavigationBar: Specify true to hide the UINavigationBar. /// - Parameter animated: Specify true to animate the transition. /// - Parameter popCompletion: Completion called when `module` is removed from the navigation stack. func setRootModule(_ module: Presentable, hideNavigationBar: Bool, animated: Bool, popCompletion: (() -> Void)?) /// Set view controllers stack of navigation controller /// - Parameters: /// - modules: The modules stack to set. /// - hideNavigationBar: Specify true to hide the UINavigationBar. /// - animated: Specify true to animate the transition. func setModules(_ modules: [NavigationModule], hideNavigationBar: Bool, animated: Bool) /// Pop to root view controller of navigation controller and remove all others /// /// - Parameter animated: Specify true to animate the transition. func popToRootModule(animated: Bool) /// Pops view controllers until the specified view controller is at the top of the navigation stack /// /// - Parameter module: The Presentable that should to be at the top of the stack. /// - Parameter animated: Specify true to animate the transition. func popToModule(_ module: Presentable, animated: Bool) /// Push a view controller on navigation controller stack /// /// - Parameter animated: Specify true to animate the transition. /// - Parameter popCompletion: Completion called when `module` is removed from the navigation stack. func push(_ module: Presentable, animated: Bool, popCompletion: (() -> Void)?) /// Push some view controllers on navigation controller stack /// /// - Parameter modules: Modules to push /// - Parameter animated: Specify true to animate the transition. func push(_ modules: [NavigationModule], animated: Bool) /// Pop last view controller from navigation controller stack /// /// - Parameter animated: Specify true to animate the transition. func popModule(animated: Bool) /// Pops all view controllers /// /// - Parameter animated: Specify true to animate the transition. func popAllModules(animated: Bool) /// Returns the modules that are currently in the navigation stack var modules: [Presentable] { get } /// Check if the navigation controller contains the given presentable. /// - Parameter module: The presentable for which to check the existence. func contains(_ module: Presentable) -> Bool } // `NavigationRouterType` default implementation extension NavigationRouterType { func setRootModule(_ module: Presentable) { setRootModule(module, hideNavigationBar: false, animated: false, popCompletion: nil) } func setRootModule(_ module: Presentable, popCompletion: (() -> Void)?) { setRootModule(module, hideNavigationBar: false, animated: false, popCompletion: popCompletion) } func setModules(_ modules: [NavigationModule], animated: Bool) { setModules(modules, hideNavigationBar: false, animated: animated) } func setModules(_ modules: [Presentable], animated: Bool) { setModules(modules, hideNavigationBar: false, animated: animated) } } // MARK: - Presentable <--> NavigationModule Transitive Methods extension NavigationRouterType { func setRootModule(_ module: NavigationModule) { setRootModule(module.presentable, popCompletion: module.popCompletion) } func push(_ module: NavigationModule, animated: Bool) { push(module.presentable, animated: animated, popCompletion: module.popCompletion) } func setModules(_ modules: [Presentable], hideNavigationBar: Bool, animated: Bool) { setModules(modules.map { $0.toModule() }, hideNavigationBar: hideNavigationBar, animated: animated) } func push(_ modules: [Presentable], animated: Bool) { push(modules.map { $0.toModule() }, animated: animated) } }