代码还是要动手写,一起来用RxSwift来写一个简单的Demo吧,动起手来,不要懒,因为这个真的很简单,但是还是能学到一些东西的。
本篇文章的完整项目及以后的RxSwift相关Demo都在: 点击这里。
我们预期的结果是这样:
准备
开始前,先在storyboard中拖几个控件。
当然,如果你想手写也是可以的,storyboard比较省时间而已。效果如下图:
<br />
<br />
然后import RxSwift
和RxCocoa
,并定义以下属性:
import RxSwift
import RxCocoa
let minUsernameLength = 5
let maxUsernameLength = 10
let minPasswordLength = 5
let maxPasswordLength = 16
let disposBag = DisposeBag()
将控件拖至相应的ViewController
:
@IBOutlet weak var usernameTF: UITextField!
@IBOutlet weak var usernameLB: UILabel!
@IBOutlet weak var passwordTF: UITextField!
@IBOutlet weak var passwordLB: UILabel!
@IBOutlet weak var loginButton: UIButton!
对输入字符串进行判断
override func viewDidLoad() {
super.viewDidLoad()
let usernameValid = usernameTF.rx_text
.map{$0.characters.count >= minUsernameLength && $0.characters.count <= maxUsernameLength } //map函数 对text进行处理
.shareReplay(1)
let passwordValid = passwordTF.rx_text
.map{$0.characters.count >= minPasswordLength && $0.characters.count < maxPasswordLength } //map函数 对text进行处理
.shareReplay(1)
}
首先,定义一个布尔值:usernameValid
来接收usernameTF
字符个数是否符合要求,同理passwordValid
接收usernameTF
字符个数是否符合要求。
.map负责对UITextField中的字符进行处理,判断字符长度,是否符合要求,将判断的值返回给usernameValid
和passwordValid
。
关于map
函数,可以参考这篇文章。
shareReplay()
是RxSwift提供的一个流操作函数,它是以重播的方式通知自己的订阅者,保证在观察者订阅这个流的时候始终都能回播最后N个,shareReplay(1)
表示重播最后一个。
然后,我们需要根据用户名和密码输入是否全部符合要求,来控制登录按钮是否可以点击:
let everythingValid = Observable.combineLatest(usernameValid, passwordValid) { (usernameValid, passwordValid) -> Bool in
usernameValid && passwordValid
}
当usernameValid
和 passwordValid
同时为true
时,everythingValid
才为true
,我们用everythingValid
来控制登录按钮是否可以点击。
上边的代码可以简化成:
let everythingValid = Observable.combineLatest(usernameValid, passwordValid) { $0 && $1 }
.shareReplay(1)
原理参考这篇文章。
绑定
usernameValid
.bindTo(passwordTF.rx_enabled) //username通过验证,passwordTF才可以输入
.addDisposableTo(disposBag)
将usernameValid
和passwordTF.rx_enabled
绑定,即用usernameValid
来控制passwordTF
是否可以输入的状态。
注意:这里我们用usernameValid
和passwordTF
的rx_enabled
绑定。通过这个绑定,只有当usernameValid
为true
时,passwordTF
才是可以输入的状态,也就是我们需要在用户名长度正确的时候,才可以输入密码,否则,密码输入框为不可出入状态。
bindTo
就是RxSwfit
中用来进行值绑定的函数。
addDisposableTo(disposBag)
订阅信号会产生Disposable。如果不销毁,那么这些生成的Disposable将会一直存在,这无疑是非常耗内存的。所以,想要释放无用的资源,可以调用dispose,但是直接调用dispose会有一个问题,就是如果调用时机不对,可能会影响到程序的正常运行。所以我们可以用addDisposableTo(disposeBag)
。类似于autoreleasepool
,由它处理资源的自动销毁。是不是有点像mrc
和arc
的区别,那么选哪个更好,就不用说了,肯定是使用addDisposableTo(disposBag)
。
接下来,将usernameTF
下边的提示label
和usernameValid
绑定:
usernameValid
.bindTo(usernameLB.rx_hidden) //username通过验证,usernameLB警告消失
.addDisposableTo(disposBag)
这样,当用户名符合要求的时候,警告消息就会隐藏,当不符合时,又会再度出现。
接下来,将其他的属性都绑定起来:
passwordValid
.bindTo(passwordLB.rx_hidden)
.addDisposableTo(disposBag)
everythingValid
.bindTo(loginButton.rx_enabled) // 用户名密码都通过验证,才可以点击按钮
.addDisposableTo(disposBag)
loginButton.rx_tap //绑定button点击事件
.subscribeNext { [weak self] in
self?.showAlert()
}
.addDisposableTo(disposBag)
在viewDidLoad()
方法外,定于一个方法,用来显示提示信息:
func showAlert() {
let alertView = UIAlertView(
title: "成功",
message: "登录成功",
delegate: nil,
cancelButtonTitle: "OK"
)
alertView.show()
}
完成
搞定,运行你的程序吧,尝试输入正确和错误位数的用户名/密码,试试看。
当都输入正确的时候,结果如下图:
本篇文章的完整项目及以后的RxSwift相关Demo都在: 点击这里。
以后就可以在自己应用中使用RxSwift
来写登录/注册界面了。当然,这才算是刚刚入门RxSwift
。以后的路还长,要学的还很多。路漫漫其修远兮 吾将上下而求索。