LiteRoute 2.1.21

LiteRoute 2.1.21

Vladislav Prusakov 维护。



LiteRoute 2.1.21

  • 作者
  • Vladislav Prusakov

LightRoute

Build Status Pod version Carthage compatible Platform License Twitter Swift

描述

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

示例

关于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:更改它。您可以使用以下方式获取自定义模块输入:

  • 通过字符串: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:)负责更改展示风格。它与UINavigationControllerUISplitViewControllerModalPresentation和默认展示一起工作。

.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()`
}

为.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)

注意

感谢观看。