LightRoute 2.1.19

LightRoute 2.1.19

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最新发布2018年9月
SPM支持 SPM

Vladislav PrusakovVladislav Prusakov 维护。



LightRoute 2.1.19

  • Vladislav Prusakov

LightRoute

Build Status Pod version Carthage compatible Platform License Twitter Swift

描述

LightRoute 是在纯 Swift 上实现的 VIPER 模块之间的简单过渡。我们可以通过与几行代码之间的转变很容易地在模块之间进行转换。

安装

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 Package Manager

一旦您设置了Swift包,将 LightRoute 添加为依赖关系就像将它添加到您的 Package.swift 中的 dependencies 值一样简单。

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")
]

示例

关于 LightRoute

LightRoute 可以与 SegueUINavigationController 和默认的视图控制器显示方式协同工作。

对于所有过渡,返回一个管理当前过渡的 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: 方法来更改它。您可以使用以下方法获取自定义的 moduleInput。

  • 通过字符串: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 是一个类,用于灵活配置您的过渡,但针对此过渡流程,您应该实现自己的过渡逻辑,并调用 set(_ didPerformCustomTransition:)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)

📌支持的风格

  • 导航风格pushpoppresent
    .to(preferred: .navigation(style: NavigationStyle))
  • 分割风格detaildefault
    .to(preferred: .split(style: SplitStyle))
  • 模态风格UIModalTransitionStyleUIModalPresentationStyle - 标准 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()`
}

Segue 过渡

您可以通过以下方式从 UIStoryboardSegue 触发过渡

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

自定义关闭样式

如果您想关闭弹出控制器或使用 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)

注意

感谢观看。