测试已验证 | ✓ |
语言语言 | SwiftSwift |
许可证 | MIT |
发布最后发布 | 2017年12月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✗ |
由 Richard Adem 维护。
ReSwift 的声明式路由器。允许开发者以类似 Web 中使用 URL 的方式声明路由。
使用 ReSwiftRouter,您可以通过定义类似 URL 的标识符序列来定义目标位置以在应用程序中进行导航
mainStore.dispatch(
SetRouteAction(["TabBarViewController", StatsViewController.identifier])
)
#关于 ReSwiftRouter
ReSwiftRouter 仍在开发中,API 目前既不完整也不稳定。
当使用 ReSwift 构建应用程序时,您应该旨在通过动作触发所有状态变化 - 这包括导航状态的变化。
这需要在应用程序状态中存储当前导航状态,并使用动作触发该状态的变化 - 这两点 ReSwiftRouter 都提供。
#安装
##CocoaPods
您可以通过将 ReSwiftRouter 添加到您的 Podfile
来使用 CocoaPods 进行安装
use_frameworks!
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'ReSwift'
pod 'ReSwiftRouter'
然后运行 pod install
。
##Carthage
您可以通过向您的 Cartfile 添加以下行来使用 Carthage 安装 ReSwiftRouter
github "ReSwift/ReSwiftRouter"
##配置
扩展您的应用程序状态以包括导航状态
import ReSwiftRouter
struct AppState: StateType {
// other application state
var navigationState: NavigationState
}
初始化您的商店后,创建一个 Router
的实例,传入商店的引用和根 Routable
。此外,您还需要提供一个描述如何访问应用程序状态的 navigationState
的闭包
router = Router(store: mainStore, rootRoutable: RootRoutable(routable: rootViewController)) { state in
state.navigationState
}
我们将在下一章讨论 Routable
。
##调用导航减法器
提供 NavigationReducer
作为 ReSwiftRouter
的一部分。您需要在顶级还原器中调用它。以下是一个简单的规范示例
struct AppReducer: Reducer {
func handleAction(action: Action, state: FakeAppState?) -> FakeAppState {
return FakeAppState(
navigationState: NavigationReducer.handleAction(action, state: state?.navigationState)
)
}
}
这将使还原器处理所有与路由相关的动作。
#实现 Routable
ReSwiftRouter 适用于以与 URL 类似的方式定义的路线,例如 ["Home", "User", "UserDetail"]
。
ReSwiftRouter 无关您使用的 UI 框架 - 它使用 Routable
来实现该交互。
将每个路由段映射到一个负责的 Routable
。该 Routable
需要能够呈现一个子节点、隐藏一个子节点或替换一个子节点为另一个子节点。
以下是包含您应实现的方法的 Routable
协议
protocol Routable {
func changeRouteSegment(from: RouteElementIdentifier,
to: RouteElementIdentifier,
completionHandler: RoutingCompletionHandler) -> Routable
func pushRouteSegment(routeElementIdentifier: RouteElementIdentifier,
completionHandler: RoutingCompletionHandler) -> Routable
func popRouteSegment(routeElementIdentifier: RouteElementIdentifier,
completionHandler: RoutingCompletionHandler)
}
作为初始化 Router
的一部分,您需要传递第一个 Routable
作为参数。该根 Routable
将负责第一个路由段。
例如,如果您将应用的路由设置为 ["Home"]
,则根 Routable
将被要求展示与标识符 "Home"
对应的视图。
当使用 UIKit 在 iOS 上工作时,这意味着 Routable
需要设置应用的重 rootViewController
。
每当 Routable
展示一个新的路由段时,它需要返回一个将负责管理展示段的新的 Routable
。如果您想从 ["Home"]
导航到 ["Home", "Users"]
,负责 "Home"
段的 Routable
将会被要求展示 "User"
段。
如果您在此过渡中使用模态展示,则 "Home"
段的 Routable
实现可能如下所示
func pushRouteSegment(identifier: RouteElementIdentifier,
completionHandler: RoutingCompletionHandler) -> Routable {
if identifier == "User" {
// 1.) Perform the transition
userViewController = UIStoryboard(name: "Main", bundle: nil)
.instantiateViewControllerWithIdentifier("UserViewController") as! Routable
// 2.) Call the `completionHandler` once the transition is complete
presentViewController(userViewController, animated: false,
completion: completionHandler)
// 3.) Return the Routable for the presented segment. For convenience
// this will often be the UIViewController itself.
return userViewController
}
// ...
}
func popRouteSegment(identifier: RouteElementIdentifier,
completionHandler: RoutingCompletionHandler) {
if identifier == "Home" {
dismissViewControllerAnimated(false, completion: completionHandler)
}
// ...
}
##在 Routables 中调用完成处理器
ReSwiftRouter 需要限制导航操作,因为许多 UI 框架(包括 UIKit)不允许并行执行多个导航步骤。因此,Routable
的每个方法都接收一个 completionHandler
。只有在完成处理器被调用后,路由器才会执行任何其他导航操作。
#更改当前路由
目前更改当前应用路由的唯一方法是通过使用 SetRouteAction
并提供绝对路由。以下是一个简短的示例
@IBAction func cancelButtonTapped(sender: UIButton) {
mainStore.dispatch(
SetRouteAction(["TabBarViewController", StatsViewController.identifier])
)
}
随着开发继续,将添加更改单个路由段的支持。
#投稿
##编译和运行测试
ReSwiftRouter 使用 Carthage 管理其开发依赖。要构建或测试任何目标,请运行 carthage bootstrap
。