LightRoute
描述
LightRoute 是一个简单的 VIPER 模块之间的切换工具,它使用纯 Swift 实现。我们可以轻松地通过几行代码在模块间进行转换。
安装
CocoaPods
将其添加到 podfile 中
pod "LightRoute"
Carthage
Carthage 是一个去中心化的依赖管理器,它构建您的依赖并提供二进制框架。
您可以使用以下命令使用 Homebrew 安装 Carthage
$ brew update
$ brew install carthage
要使用 Carthage 将 LightRoute 集成到 Xcode 项目中,请在您的 Cartfile
中指定它
github "SpectralDragon/LightRoute" ~> 2.1
运行 carthage update
以构建框架,并将构建好的 LightRoute.framework
拖放到您的 Xcode 项目中。
Swift包管理器
一旦您已经设置了Swift包,将LightRoute添加为依赖就像将其添加到Package.swift
中的依赖项值一样简单。
Swift 3
dependencies: [
.Package(url: "https://github.com/SpectralDragon/LightRoute.git", majorVersion: 2)
]
Swift 4
dependencies: [
.package(url: "https://github.com/SpectralDragon/LightRoute.git", from: "2.1")
]
示例
- 新示例项目: iOS 示例
- 旧示例项目: Viper-LightRoute-Swinject
关于LightRoute
LightRoute可以与Segue
、UINavigationController
以及默认视图控制器显示一起工作。
对于所有转换,返回管理当前转换的TransitionNode
实例。您可以更改转换流程,像您想要的那样。
如何使用
例如,我们将实现两个VIPER模块之间的转换
import LightRoute
// MARK: - The module initiating the transition.
protocol FirstViperRouterInput: class {
func openModule(userIdentifier: String)
}
final class FirstViperRouter: FirstViperRouterInput {
// This property contain protocol protected view controller for transition.
weak var transitionHandler: TransitionHandler!
// View controller identifier for current storyboard.
let viewControllerIdentifier = "SecondViperViewController"
func openModule(userIdentifier: String) {
try? transitionHandler
// Initiates the opening of a new view controller.
.forCurrentStoryboard(resterationId: viewControllerIdentifier, to: SecondViperViewControllerModuleInput.self)
// Set animate for transition.
.transition(animate: false)
// Set transition case.
.to(preffered: TransitionStyle.navigation(style: .push))
// View controller init block.
.then { moduleInput in
moduleInput.configure(with: userIdentifier)
}
}
}
// MARK: - The module at which the jump occurs.
// Module input protocol for initialize
protocol SecondViperViewControllerModuleInput: class {
func configure(with userIdentifier: String)
}
final class SecondViperPresenter: SecondViperViewControllerModuleInput, ... {
// Implementation protocol
func configure(with userIdentifier: String) {
print("User identifier", userIdentifier) // Print it!
// Initialize code..
}
}
在这种情况下,您会创建默认视图控制器之间的转换并按您的意愿配置模块输入。但您也可以仅使用视图控制器,示例
.forCurrentStoryboard(resterationId: viewControllerIdentifier, to: SecondViperPresenter.self)
/// and etc..
注意moduleInput
- 默认情况下,该属性包含目标视图控制器中的output
属性。您可以使用方法selector:
更改它。您可以使用以下方式获取自定义模块输入:
- 通过字符串:
selector(_ selector: String)
- 通过选择器:
selector(_ selector: Selector)
- 通过键路径:
selector(_ selector: KeyPath)
转换情况
例如,我们分析此代码,然后包含两个用于与转换一起工作的案例
第一案例
这是默认情况,带有默认LightRoute实现。如果您只想显示新模块,则可以使用该功能
try? transitionHandler
// Initiates the opening of a new view controller.
.forCurrentStoryboard(resterationId: viewControllerIdentifier, to: SecondViperViewControllerModuleInput.self)
// Setup module input.
.then { moduleInput in
moduleInput.configure(with: "Hello!")
}
第二案例
但第一种方法不能灵活,因为那有一个customTransition()
方法。这个方法返回CustomTransitionNode
。该节点不支持默认的TransitionNode
方法。CustomTransitionNode
是一个类,它提供灵活的设置你过渡的方法,但对于这个过渡流程,你应该实现你的过渡逻辑,并调用them(_:)
或perform()
方法来激活过渡。
示例
try? transitionHandler
// Initiates the opening of a new view controller.
.forCurrentStoryboard(resterationId: viewControllerIdentifier, to: SecondViperViewControllerModuleInput.self)
// Activate custom transition.
.customTransition()
// Custom transition case.
.transition { source, destination in
// Implement here your transition logic, like that:
// source.present(destination, animated: true, completion: nil)
}
// Setup module input.
.then { moduleInput in
moduleInput.configure(with: "Hello custom transition!")
}
自定义过渡
要自定义过渡,你可以更改过渡展示并设置动画。
动画过渡
这些方法可以对你的当前过渡进行动画处理。
.transition(animate: false)
更改展示
方法to(preffered:)
负责更改展示风格。它与UINavigationController
,UISplitViewController
,ModalPresentation
和默认展示一起工作。
.to(preferred: TransitionStyle)
- 导航风格(
push
、pop
、present
).to(preferred: .navigation(style: NavigationStyle))
- 分割风格(
detail
、default
).to(preferred: .split(style: SplitStyle))
- 模态风格(
UIModalTransitionStyle
、UIModalPresentationStyle
- 标准UIKit的展示风格。).to(preferred: .modal(style: style: (transition: UIModalTransitionStyle, presentation: UIModalPresentationStyle)))
配置目标控制器
有时你需要在你控制器中添加额外的依赖。在这种情况下,将添加apply(to:)
方法。该方法返回目标控制器,你可以对其进行配置。
try? transitionHandler
.forSegue(identifier: "LightRouteSegue", to: SecondViperViewControllerModuleInput.self)
.apply(to: { controller in
// configure your controller.
})
.then { moduleInput in
// configure your module
}
在新故事板上过渡
同样,LightRoute也可以像这样在新故事板实例上进行过渡
// We remeber this class :)
func openModule(userIdentifier: String) {
let storyboard = UIStoryboard(name: "NewStoryboard", bundle: Bundle.main)
let factory = StoryboardFactory(storyboard: storyboard)
try? transitionHandler
// Initiates the opening of a new view controller from custom `UIStoryboard`.
.forStoryboard(factory: factory, to: SecondViperViewControllerModuleInput.self)
// Set animate for transition.
.transition(animate: false)
// View controller init block.
.then { moduleInput in
moduleInput.configure(with: userIdentifier)
} // If you don't want initialize view controller, we should be use `.perform()`
}
为.ToString
你可以从StoryboardSegue
开始过渡,如下所示:
func openModule(userIdentifier: String) {
try? transitionHandler
// Performs transition from segue and cast to need type
.forSegue(identifier: "LightRouteSegue", to: SecondViperViewControllerModuleInput.self)
.then { moduleInput in
moduleInput.setup(text: "Segue transition!")
}
}
如果你想使用EmbedSegue
,需要在故事板中添加segue,设置类为EmbedSegue
,并且源视图控制器必须遵循协议ViewContainerForEmbedSegue
,如下所示:
extension SourceViewController: ViewContainerForEmbedSegue {
func containerViewForSegue(_ identifier: String) -> UIView {
return embedView
}
}
然后你可以这样开始EmbedSegue
过渡:
func addEmbedModule() {
try? transitionHandler
.forSegue(identifier: "LightRouteEmbedSegue", to: EmbedModuleInput.self)
.perform()
}
关闭当前模块
如果你想开始关闭当前模块,你应该使用
.closeCurrentModule()
然后你可以使用perform()
方法来启动关闭方法。
动画关闭过渡
这些方法可以对你的当前过渡进行动画处理。
.transition(animate: false)
注意:默认值为true
自定义关闭风格
如果你想要关闭pop控制器或使用popToRoot控制器,你必须执行方法preferred(style:)
。此方法针对你的关闭过渡有不同的风格。
如果你需要在自定义控制器中调用 popToViewController(:animated)
,你必须执行方法 find(pop>:
).
try? transitionHandler
.closeCurrentModule()
.find(pop: { controller -> Bool
return controller is MyCustomController
})
.preferred(style: .navigation(style: .findedPop))
.perform()
支持 UIViewControllerTransitioningDelegate
LightRoute 2.0 现在开始支持 UIViewControllerTransitioningDelegate 用于过渡。我们可以使用以下方法进行操作
.add(transitioningDelegate: UIViewControllerTransitioningDelegate)
注意
- 由 ViperMcFlurry 创造
- 许可证:
MIT
- 作者:Vladislav Prusakov / [email protected]
感谢观看。