RxSwift 案例学习(一)
本文是官方案例GitHubSignup-UsingDriver学习笔记
项目实现功能
这个登录页面实现了下面几个功能: 1.检验用户名是否可用 2.密码是否符合要求 3.确认密码是符合密码一样 4.上面上面三个都符合要求,登录按钮才可以点击 5.当用户正在登录的时候,显示 activityIndicator,提醒用户等待,此时按钮不能被按;当得到登录结果的时候,隐藏 activityIndicator。 6.登录完成显示登录结果
具体实现
GitHubSignupViewController2.swift
#if !RX_NO_MODULE
import RxSwift
import RxCocoa
#endif
复制代码
引用部分RX_NO_MODULE这个宏的字面意思应该是没有rx的模块意思,但是没有找到具体实现在哪里,如果谁知道麻烦告知
@IBOutlet weak var usernameOutlet: UITextField!@IBOutlet weak var usernameValidationOutlet: UILabel!@IBOutlet weak var passwordOutlet: UITextField!@IBOutlet weak var passwordValidationOutlet: UILabel!@IBOutlet weak var repeatedPasswordOutlet: UITextField!@IBOutlet weak var repeatedPasswordValidationOutlet: UILabel!@IBOutlet weak var signupOutlet: UIButton!@IBOutlet weak var signingUpOulet: UIActivityIndicatorView!
复制代码
首先是各个控件的绑定
let viewModel = GithubSignupViewModel2(input: (username: usernameOutlet.rx.text.orEmpty.asDriver(),password: passwordOutlet.rx.text.orEmpty.asDriver(),repeatedPassword: repeatedPasswordOutlet.rx.text.orEmpty.asDriver(),loginTaps: signupOutlet.rx.tap.asDriver()),dependency: (API: GitHubDefaultAPI.sharedAPI,validationService: GitHubDefaultValidationService.sharedValidationService,wireframe: DefaultWireframe.sharedInstance))
复制代码
viewModel初始化,rx是RxSwift的域名,text是观察的属性,orEmpty是检验text是否为nil如果为nil返回"",asDriver()是具体特殊属性的Observable,如果使用asObservable(),就要额外添加.observeOn(MainScheduler.instance)和.shareReplay(1), Driver是属于Rxcocoa库,是对Observable进行了一些封装,Observable是属于RxSwift库
viewModel.signupEnabled.drive(onNext: { [weak self] valid inself?.signupOutlet.isEnabled = validself?.signupOutlet.alpha = valid ? 1.0 : 0.5}).addDisposableTo(disposeBag)
复制代码
监听viewModel.signupEnabled的值变化,signupEnabled的类型为 Driver,那么valid的类型就为Bool,根据valid来设置按钮的状态
viewModel.validatedUsername.drive(usernameValidationOutlet.rx.validationResult).addDisposableTo(disposeBag)viewModel.validatedPassword.drive(passwordValidationOutlet.rx.validationResult).addDisposableTo(disposeBag)viewModel.validatedPasswordRepeated.drive(repeatedPasswordValidationOutlet.rx.validationResult).addDisposableTo(disposeBag)viewModel.signingIn.drive(signingUpOulet.rx.isAnimating).addDisposableTo(disposeBag)复制代码
将viewModel.validatedUsername和UILabel的validationResult绑定, validationResult是UILabel自定义的Rx扩展,源码如下:
extension Reactive where Base: UILabel {var validationResult: UIBindingObserver<Base, ValidationResult> {return UIBindingObserver(UIElement: base) { label, result inlabel.textColor = result.textColorlabel.text = result.description}}
}
复制代码
let tapBackground = UITapGestureRecognizer()tapBackground.rx.event.subscribe(onNext: { [weak self] _ inself?.view.endEditing(true)}).addDisposableTo(disposeBag)view.addGestureRecognizer(tapBackground)
复制代码
以上是新建一个tap手势并使用Rx对手势的监听来实现相应的功能
GithubSignupViewModel2.swift
init(input: (username: Driver<String>,password: Driver<String>,repeatedPassword: Driver<String>,loginTaps: Driver<Void>),dependency: (API: GitHubAPI,validationService: GitHubValidationService,wireframe: Wireframe))
复制代码
首先是初始化接受一个两个元组作为参数
validatedUsername = input.username.distinctUntilChanged() //demo重复检查.flatMapLatest { username inreturn validationService.validateUsername(username).asDriver(onErrorJustReturn: .failed(message: "Error contacting server"))}validatedPassword = input.password.map { password inreturn validationService.validatePassword(password)}
复制代码
对username和password的值进行处理,然后返回Driver的结果为后面处理做准备
validatedPasswordRepeated = Driver.combineLatest(input.password, input.repeatedPassword, resultSelector: validationService.validateRepeatedPassword)
复制代码
Driver.combineLatest将两个流合并成一个流,通过对源码的阅读发现combineLatest最多支持8路流合并成一路流, resultSelector提供多路流合并的方法,这里可以写成闭包的形式,也可以直接传入一个处理函数.
let signingIn = ActivityIndicator()
复制代码
ActivityIndicator提供检测网络访问状态的方法
self.signingIn = signingIn.asDriver()
复制代码
提供网络访问的状态监听
.trackActivity(signingIn)
复制代码
在网络请求时添加到上面的方法,可以监听网络状态,网络开始访问时返回true,网络访问结束时返回false
signedIn = input.loginTaps.withLatestFrom(usernameAndPassword).flatMapLatest { (username, password) inreturn API.signup(username, password: password).trackActivity(signingIn).asDriver(onErrorJustReturn: false)}.flatMapLatest { loggedIn -> Driver<Bool> inlet message = loggedIn ? "Mock: Signed in to GitHub." : "Mock: Sign in to GitHub failed"return wireframe.promptFor(message, cancelAction: "OK", actions: [])// propagate original value.map { _ inloggedIn}.asDriver(onErrorJustReturn: false)}
复制代码
每次登录按钮点击的时候,利用.withLatestFrom(usernameAndPassword)从usernameAndPassword中获取用户名和密码,然后传给网络请求进行访问,然后显示登录结果,并返回登录结果给上层处理
signupEnabled = Driver.combineLatest(validatedUsername,validatedPassword,validatedPasswordRepeated,signingIn) { username, password, repeatPassword, signingIn inusername.isValid &&password.isValid &&repeatPassword.isValid &&!signingIn}.distinctUntilChanged()
复制代码
通过validatedUsername, validatedPassword, validatedPasswordRepeated, signingIn四个事件流的状态来决定signupEnabled的状态,也就是决定登录按钮的状态
RxSwift 案例学习(一)相关推荐
- 通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本...
通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本 版权声明: 本文遵循"署名非商业性使用相同方式共享 2.5 中国大陆"协议 ...
- 《大数据导论》——1.4节案例学习背景
本节书摘来自华章社区<大数据导论>一书中的第1章,第1.4节案例学习背景,作者瓦吉德·哈塔克(Wajid Khattak),保罗·布勒(Paul Buhler),更多章节内容可以访问云栖社 ...
- ArcGIS案例学习1_2
ArcGIS案例学习1_2 联系方式:向日葵,135_4855_4328, xiexiaokui#qq.com 时间:第一天下午 案例1:矢量提取,栅格提取和坐标系投影变换 目的:认识数据类型 教程: ...
- 零元学Expression Blend 4 ndash; Chapter 21 以实作案例学习MouseDragElementBehavior
原文:零元学Expression Blend 4 – Chapter 21 以实作案例学习MouseDragElementBehavior 本章将教大家如何运用Blend 4内建的行为注入元件「Mou ...
- ArcGIS案例学习笔记-找出最近距离的垂线
ArcGIS案例学习笔记-找出最近距离的垂线 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 目的:对于任意矢量要素类,查找最近距离并做图 数据: 方法: 0. 计算 ...
- ArcGIS案例学习笔记2_2_等高线生成DEM和三维景观动画
ArcGIS案例学习笔记2_2_等高线生成DEM和三维景观动画 计划时间:第二天下午 教程:Pdf/405 数据:ch9/ex3 方法: 1. 创建DEM SA工具箱/插值分析/地形转栅格 2. 生成 ...
- 案例学习BlazeDS+Spring之一(
BlazeDS4的一个亮点就是与Spring的集成,这大大简化了与FLASH与JEE的集成开发.通过理解BlazeDS4附带的那些精湛的小DEMO,可以很快速的掌握这门技术.虽然案例学习这种方式不太利 ...
- 《大数据导论》一1.4 案例学习背景
本节书摘来自华章出版社<大数据导论>一书中的第1章,第1.4节,作者托马斯·埃尔(Thomas Erl),瓦吉德·哈塔克(Wajid Khattak),保罗·布勒(Paul Buhler) ...
- ArcGIS模型构建器案例学习笔记-字段处理模型集
ArcGIS模型构建器案例学习笔记-字段处理模型集 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 由四个子模型组成 子模型1:判断字段是否存在 方法:python工 ...
最新文章
- TP3.2.3 页面跳转后 Cookie 失效 —— 参考解决方案
- 记录QT片断1-(痛苦的win32)
- php 一致性hash,【转载】memcache分布式 [一致性hash算法] 的php实现
- Introduction to Big Data with Apache Spark 课程总结
- java打印 a b c,创建一个java程序,按顺序给出3个术语作为输入(a,b,c)打印它们的根...
- order by、group by也会使用索引?使用这俩关键字的时候索引什么时间会失效
- MySQL 数据库修改登录密码
- Html跨页面调用函数,一个cshtml如何在另一个cshtml中调用一个函数?
- VS Code的golang开发配置 之 代码提示
- 字符三角形(信息学奥赛一本通-T1004)
- faster-rcnn tensorflow windows demo运行
- NPOI从数据库中导出数据到Excel
- Gitweb源码解析
- 解读《美国国家BIM标准》– BIM能力成熟度模型(九)
- cl.nd77.pw index.php,Loop in template
- 微信小程序实现扫码登录网站
- apache Ignite 安装和helloworld
- 向量检索基础方法总结
- mac打开注册机显示“您没有权限来打开应用程序
- 关于通过邮箱找回密码的实现
热门文章
- freertos zynq 移植_Zynq-7000 FreeRTOS(一)系统移植配置
- 下载的TXT小说如何去除广告、去除多余空行?
- 数据挖掘与分析 - 用JS实现推荐系统的原理与开发
- 批量修改文件名称(Python)
- mysql建立pdm模型_如何使用PowerDesigner创建物理数据模型(PDM)
- c2c网站开店的流程图_shopee开店入驻?Shopee选品为什么这么重要
- redis和memecache有什么区别?
- linux终端密码星星,如何在Ubuntu终端中显示密码星号
- 服务器安全性文档,Microsoft Web服务器的安全性
- oracle log block size,案例:Oracle无法启动报错ORA-00218: block size 0 重建控制文件