iOS MVVM 与 RxSwift
2016-07-18 20:43
309 查看
MVVM
Model:数据模型View:UI展示
ViewModel:逻辑处理
架构解决问题:
viewcontroller太重,ui布局与逻辑处理没有很好的区分开来。所以一个viewcontroller的文件,很容易就写到几千行。
将逻辑处理内容区分开来,专门放到一个类里去处理,就出现了viewmodel,连接view 和 model。
model:
class UserModel: NSObject { var userName:String = "" var password:String = "" }
viewModel:
var userModel:PublishSubject<UserModel?> override init() { userModel = PublishSubject() } func loginAction(userName:String, password:String)
view:
var userViewModel = UserViewModel() @IBOutlet weak var userNameTextField: UITextField! @IBOutlet weak var passwordTextField: UITextField! @IBOutlet weak var loginButton: UIButton!
整体项目功能:
1、登录页面 (view)
2、调用登录 (viewmodel)
3、返回数据 (model)
4、数据赋值(viewmodel)
5、页面变化(view)
RxSwift
响应式编程,简化层级架构之间的通信,不用依靠delegate、notification,代码结构更加清晰。察值:
view:观察viewModel中的userModel是否发生变化。如果发生变化,根据userModel的内容,判定是否登录成功
self.userViewModel.userModel.subscribeNext({ UserModel in if (UserModel == nil) { print("登录失败") } else { print("登录成功") } }).addDisposableTo(disposeBag)
viewmodel:注意持有的model的类型(见最上viewmodel内容图)
PublishSubject:只会把在订阅发生的时间点之后来自原始Observable的数据发射给观察者。
BehaviorSubject:当观察者订阅 BehaviorSubject 时,它开始发射原始 Observable 最近发射的数据(如果此时还没有收到任何数据,它会发射一个默认值),然后继续发射其它任何来自原始Observable的数据。
Variable:封装了 BehaviorSubject 。使用 variable 的好处是 variable 将不会显式的发送 Error 或者 Completed 。在 deallocated 的时候, Variable 会自动的发送 complete 事件。
ReplaySubject:会发射所有来自原始Observable的数据给观察者,无论它们是何时订阅的。当一个新的 observer 订阅了一个 ReplaySubject 之后,他将会收到当前缓存在 buffer 中的数据和这之后产生的新数据
改值
判断输入框的输入长度是否达到指定长度
let userNameValid = userNameTextField.rx_text.map{ $0.characters.count >= minimalUsernameLength }.shareReplay(1) let passwordValid = passwordTextField.rx_text.map{ $0.characters.count >= minimalPasswordLength }.shareReplay(1)
将姓名和密码的输入框,文字类型的信号,根据长度,转换成了波尔类型的信号
map:通过对Observable发射映射的函数对每一项做转换
flatMap:将每个 Obserable 发射的数据变换为 Observable 的集合,然后将其 “拍扁”(降维 flatten)成一个 Observable。
scan:scan连续的对序列中的元素应用某一个元素。然后把结果作为下一次的输入
合并
当两个输入框输入长度都达标时,登录按钮才可以点击
let everythingValid = Observable.combineLatest(userNameValid, passwordValid) { $0 && $1 }.shareReplay(1) everythingValid.bindTo(loginButton.rx_enabled).addDisposableTo(disposeBag) everythingValid.subscribeNext { [weak self] Bool in if (Bool) { self?.loginButton.backgroundColor = UIColor.redColor() } else { self?.loginButton.backgroundColor = UIColor.lightGrayColor() } }.addDisposableTo(disposeBag)
合并了两个信号量,绑定给了button的enalbed属性,并且根据不同的enable信号,button的背景色不同。
combineLatest:当两个Observables中任意一个发送了数据,使用一个函数把两个Observable中最近的数据进行结合
startWith:在数据序列的开头增加一些数据
zip:它会等到Observable中的数据一一对应结合时,再发送数据
merge:合并多个 Observables 的组合成一个
switchLatest:将一个发射多个 Observables 的 Observable 转换成另一个单独的 Observable,后者发射那些 Observables 最近发射的数据项
demo地址:https://github.com/piang/iOSMVVMRxSwift
相关文章推荐
- swift 学习笔记四
- 探索原生Swift的模式
- Swift 中枚举高级用法及实践
- Swift-一步步教你上传头像
- Swift - Alamofire简单GET和POST使用
- swift-tabBar
- Swift中文教程(二十三) 高级运算符
- Swift中文教程(二十二) 泛型
- Swift中文教程(二十一) 协议
- Swift中文教程(二十) 扩展
- Swift中文教程(十九) 类型嵌套
- Swift中文教程(十八) 类型检查
- swift实现删除图片时的抖动动画
- c、rust、golang、swift性能比较
- 解析Swift中闭包的循环引用
- Swift - 不使用pods如何正确添加类似Alamofire这样的库
- Swift语法之 ---- ?和!区别
- OC/Swift 根据label字数字体返回实际高度
- swift 中的 感叹号 问号 和 双问号用法详解
- KVO and Swift