用 RxSwift 实现通用的响应式转场

本文讲的是用 RxSwift 实现通用的响应式转场,


个人而言,我喜欢 UIStoryboardSegue 这个类背后的思路,把导航逻辑从业务逻辑程序中分离出来。

但是我并不推崇通过 storyboard 来实现这个方法,并且我也从来没有在代码中实现过。

所以我决定吸取上文的思想,自己做一个类似的东西。

但是这个类型应该有哪些域呢?

当然必须要有

 let fromViewController:UIViewController

很多人会把想要显示的 context 传递给下一个 ViewController。

因为 Swift 有一个很酷的功能叫泛型,我们可以利用它把 context 变成通用类型 T

同时,我们还需要创建 toViewController 对象,我决定用 block 来做

let toViewControllerFactory:(context:T) -> UIViewController

现在我们可以实现转场的“响应式”部分了 =)

转场可以做两件事—— push 新的 viewController ,或者以模式方式显示。

private(set) lazy var pushObserver:AnyObserver

private(set) lazy var presentObserver:AnyObserver

我们来实现这些 observers

import UIKit
import RxSwift

class Segue {

   private(set) weak var fromViewController:UIViewController?
   let toViewControllerFactory:(context:T) -> UIViewController

   init(fromViewController:UIViewController,
      toViewControllerFactory:(context:T) -> UIViewController) {
         self.fromViewController = fromViewController
         self.toViewControllerFactory = toViewControllerFactory
   }

   private(set) lazy var pushObserver:AnyObserver = AnyObserver {[weak self] event in
      switch event {
      case .Next(let value):
         guard let strong = self else {return}
         let toViewController = strong.toViewControllerFactory(context: value)
         strong.fromViewController?.navigationController?
            .pushViewController(toViewController, animated:true)
      default:
         break
      }
   }

   private(set) lazy var presentObserver:AnyObserver = AnyObserver {[weak self] event in
      switch event {
      case .Next(let value):
         guard let strong = self else {return}
         let toViewController = strong.toViewControllerFactory(context: value)
         strong.fromViewController?.presentViewController(toViewController, animated: true, completion: nil)
      default:
         break
      }
   }

}

注意:如果你不想在转场中传递 context ,需要把它创建成 Void 类型

lazy var segue:Segue

现在我们可以这样使用转场了:

import RxSwift
import RxCocoa

class SomeTableViewController:UITableViewController {
  let disposeBag = DisposeBag()
  let items:[Item] ...

  lazy var itemDetailsSegue:Segue = {
      return Segue(fromViewController: self,
              toViewControllerFactory: { context -> UIViewController in
                  return ItemDetailsViewController(item:context)
              })
  }

    lazy var voidModalSegue:Segue = {
      return Segue(fromViewController: self,
              toViewControllerFactory: { _ -> UIViewController in
                  return SomeViewController()
              })
  }

    override func viewDidLoad() {
      super.viewDidLoad()

      someButton.rx_tap
            .bindTo(voidModalSegue.presentObserver)
            .addDisposableTo(disposeBag)

      tableView.rx_itemSelected
            .map({[unowned self] indexPath in self.items.[indexPath.row]})
            .bindTo(itemDetailsSegue.pushObserver)
            .addDisposableTo(disposeBag)
    }

}

结果如何?导航逻辑被分离出来了,而且这个类很容易进行单元测试。

大家有什么想法评论,欢迎留言讨论 :)





原文发布时间为:2016年09月10日


本文来自合作伙伴掘金,了解相关信息可以关注掘金网站。

时间: 2024-08-02 13:20:09

用 RxSwift 实现通用的响应式转场的相关文章

非响应式设计的viewport

整理自:Viewport Meta Tag For Non-Responsive Design 中文原文:非响应式设计的viewport 请尊重版权,转载请注明来源,多谢-- 大家已经非常熟悉响应式网页设计了吧,但是我们通常会忽略很多旧的没有采用响应式设计的网站,其实这类网站在移动终端的用户体验更为关键--因为它们没有对移动设备做任何优化. 通用viewport 对于响应式网站,大家通常都会这样定义: 1 <meta name="viewport" content="w

响应式页面重构 响应式页面重构学到的东西

文章描述:关于响应式页面 作为一个无线部门的人,不懂移动设备是不行的.而作为一个无线的重构,不会写响应式页面更是不行得.而我,一个无线的重构,在我最近做的一个移动端的项目之前,的确是不会写响应式页面的,所以,严格来说,在这个项目之前,我是一个不合格的无线重构人. 而这个项目,却让我快速地掌握了响应式页面重构的一些方法.下面就是通过这个项目来总结我在响应式页面重构学到的东西. 众所周知,所谓响应式页面,就是能够用一套样式,使你的页面能够在不同分辨率的屏幕下都有很好的表现形式.响应式Web设计,这个

五大技巧帮你提速响应式网页设计项目

  没有哪个成功的Web项目是在设计师和开发无法流畅沟通的前提下搞定的,协作才是做好项目的基础. 我曾看到经验丰富的设计师和开发者因为沟通不畅和误会导致项目失败,也见过新手设计师和开发团队一起通过高效协同,做出惊艳无比的设计项目.在项目之初充分的磨合,能让项目在后续的快速迭代中更为流畅.足够和谐的沟通不仅有利于工作,而且能让整个团队保持情绪的稳定性. 而在响应式网页设计项目中,设计师和开发者之间的沟通流畅与否,就显得更为重要. 设计响应式网站的时候,整个团队必须为大量不同尺寸屏幕的设备充分考虑,

深聊MATERIAL DESIGN复杂响应式设计

  2011年,Gmail邮箱的按钮变得更加扁平化.2012年,Google引入分层的卡片设计,使用更多的空白和精心设计的层次排版结构.经历了几年的迭代和提炼,Google寻找到了一种可以贯通的理论体系,即把系统内的各种设计都规范成一种变形的纸片,并套用现实中纸墨的物理模型进行交互,这就是2014年Google I/O大会隆重发布的Material Design. Material Design提出了平面像素的Z轴概念,通过纸片在物理世界中形态的抽象和提炼,定义了各种信息层级和常用状态的表达方式

网页研究:关于响应式页面

作为一个无线部门的人,不懂移动设备是不行的.而作为一个无线的重构,不会写响应式页面更是不行得.而我,一个无线的重构,在我最近做的一个移动端的项目之前,的确是不会写响应式页面的,所以,严格来说,在这个项目之前,我是一个不合格的无线重构人. 而这个项目,却让我快速地掌握了响应式页面重构的一些方法.下面就是通过这个项目来总结我在响应式页面重构学到的东西. 众所周知,所谓响应式页面,就是能够用一套样式,使你的页面能够在不同分辨率的屏幕下都有很好的表现形式.响应式Web设计,这个概念是Ethan Marc

网站设计分析:响应式页面的几个关键组成部

    作为一个无线部门的人,不懂移动设备是不行的.而作为一个无线的重构,不会写响应式页面更是不行得.而我,一个无线的重构,在我最近做的一个移动端的项目之前,的确是不会写响应式页面的,所以,严格来说,在这个项目之前,我是一个不合格的无线重构人. 而这个项目,却让我快速地掌握了响应式页面重构的一些方法.下面就是通过这个项目来总结我在响应式页面重构学到的东西. 众所周知,所谓响应式页面,就是能够用一套样式,使你的页面能够在不同分辨率的屏幕下都有很好的表现形式.响应式Web设计,这个概念是Ethan

迅雷CUED:关于响应式页面设计

  作为一个无线部门的人,不懂移动设备是不行的.而作为一个无线的重构,不会写响应式页面更是不行得.而我,一个无线的重构,在我最近做的一个移动端的项目之前,的确是不会写响应式页面的,所以,严格来说,在这个项目之前,我是一个不合格的无线重构人. 而这个项目,却让我快速地掌握了响应式页面重构的一些方法.下面就是通过这个项目来总结我在响应式页面重构学到的东西. 众所周知,所谓响应式页面,就是能够用一套样式,使你的页面能够在不同分辨率的屏幕下都有很好的表现形式.响应式Web设计,这个概念是Ethan Ma

【转】构建需求响应式亿级商品详情页

商品详情页是什么 商品详情页是展示商品详细信息的一个页面,承载在网站的大部分流量和订单的入口.京东商城目前有通用版.全球购.闪购.易车.惠买车.服装.拼购.今日抄底等许多套模板.各套模板的元数据是一样的,只是展示方式不一样.目前商品详情页个性化需求非常多,数据来源也是非常多的,而且许多基础服务做不了的都放我们这,因此我们需要一种架构能快速响应和优雅的解决这些需求问题.因此我们重新设计了商品详情页的架构,主要包括三部分:商品详情页系统.商品详情页统一服务系统和商品详情页动态服务系统:商品详情页系统

Windows10 UWP开发 - 响应式设计

原文:Windows10 UWP开发 - 响应式设计   Windows10 UWP开发 - 响应式设计 本篇随笔与大家简单讨论一下在开发适配不同分辨率.宽高比的Windows10 Universal App布局时的可行方式与小技巧.经验均从实践中总结,可能有诸多不完善和浅薄之处,欢迎读者严格指正.另外本文也只是抛砖引玉之用,希望能收获更多更好的实战经验. 自适配的必要性 说了这么多,我们首先可能会问了,为什么要做响应式设计?其原因有以下两点: Windows10的跨平台性 Windows10是