上篇文章呢,我们介绍了RxSwift的由来、集成、优势以及UILabel、Timer的使用,这里这些内容就不再介绍了
下面介绍一下今天的主角UIButton
UIButton可以说是我们开发中最常用的控件之一了,那么RxSwift又为UIButton提供了哪些更实用的功能?
这里我们先说一下普通UIButton的使用,当我们要使用一个Button的时候我们要经历两部
1、UIButton的初始化,布局(代码、Xib、storyboard都行)
2、添加点击事件,在点击事件里我们添加执行事件
而使用RxSwift的步骤和上面普通创建是一样的,说到这里那我们还用RxSwift干什么?
这里虽然都一样但是有一个非常明显的区别就是代码更清晰、更易懂
下面就看一下二者的区别,这里呢都是使用Xib创建的按钮
//RxSwift
@IBOutlet weak var RxSwiftButton: UIButton!
//普通
@IBOutlet weak var oneButton: UIButton!
1、普通版本点击事件
@IBAction func ordinaryAction(_ sender: Any) {
showMessage("普通版本的点击事件")
}
2、RxSwift版本点击事件
RxSwiftButton.rx.tap.subscribe(onNext: { [weak self] in
self!.showMessage("RxSwift写法被点击")
}).disposed(by: disposeBag)
看到这里,大家是不是认为RxSwift代码量比普通还多呢,其实在我们开发过程中一个页面可能有非常多UIButton同时还有对应的点击事件,而每一个点击事件还要执行不同的事件,当我们按照普通的创建方式一个页面点击事件过多的时候,我们查看点击事件执行的内容是不是就会很麻烦(纯代码写会更麻烦),因为我们要查看这个UIButton是做什么的,才能找到对应的方法。
而有了RxSwift就不一样了,从上面代码我们可以清晰的知道每一个UIButton都是通过闭包的方式接收点击事件的,也就是知道按钮就知道了他要做的事情,而我们使用普通的代码、xib、storyboard可能还要去布局去找对应的对应的方法,这样对我们开发来说并不快捷。而RxSwift就很好的解决了这个痛点。
介绍完RxSwfit下UIBtton优势,我们就要开始讲解它的使用了,上面点击事件介绍完了,这里我们介绍一下展示
// MARK:- Button 内容 图片的绑定
func bindToButton() {
//定时器的创建
let timer = Observable.interval(1, scheduler: MainScheduler.instance)
//普通的文本绑定
timer.map { return "计算时间:\($0)" }.bind(to: RxSwiftButton.rx.title()).disposed(by: disposeBag)
//富文本
timer.map(bindAttributedTitle(ms:)).bind(to: RxSwiftButton.rx.attributedTitle()).disposed(by: disposeBag)
//绑定图片,通过闭包返回的UIImage绑定到Button的Image属性上
timer.map({
let string = $0 % 2 == 1 ? "img_operation_success" : "img_operation_failure"
return UIImage(named: string)!
}).bind(to: RxSwiftButton.rx.image()).disposed(by: disposeBag)
//绑定背景图片,通过闭包返回的UIImage绑定到Button的Image属性上
timer.map({
let string = $0 % 2 == 1 ? "img_operation_success" : "img_operation_failure"
return UIImage(named: string)!
}).bind(to: RxSwiftButton.rx.backgroundImage()).disposed(by: disposeBag)
}
// 将数字转成对应的富文本
func bindAttributedTitle(ms: NSInteger) -> NSMutableAttributedString {
let string = String(format: "%0.2d:%0.2d.%0.1d",
arguments: [(ms / 600) % 600, (ms % 600 ) / 10, ms % 10])
//富文本设置
let attributeString = NSMutableAttributedString(string: string)
//从文本0开始6个字符字体HelveticaNeue-Bold,16号
attributeString.addAttribute(NSAttributedString.Key.font,
value: UIFont(name: "HelveticaNeue-Bold", size: 16)!,
range: NSMakeRange(0, 5))
//设置字体颜色
attributeString.addAttribute(NSAttributedString.Key.foregroundColor,
value: UIColor.white, range: NSMakeRange(0, 5))
//设置文字背景颜色
attributeString.addAttribute(NSAttributedString.Key.backgroundColor,
value: UIColor.orange, range: NSMakeRange(0, 5))
return attributeString
}
其实到这里我们对RxSwfit下的Button的常用使用方式基本就完事了,下面我们对UIButton进一步扩展,在开发过程我们也会遇到存在多个按钮,存在选中和未选中状态,效果如下
点击其中任意一个其他状态取消,通常我们就要写用tag获取点击是那个UIButton然后遍历所有的UIButton,一样的变为选中、不一样取消选中即可,可是这样写会很麻烦,而使用RxSwfit就会得到很好解决
// MARK: - 多个按钮之间的点击事件
func moreButton() {
//将所有的按钮直接放到一个Array里
let btns = [oneButton,twoButton,threeButton].map({$0!})
//创建一个可观察序列,它可以发送最后一次点击的按钮(也就是我们需要选中的按钮)
let selectButton = Observable.from(btns.map({ btn in
btn.rx.tap.map({btn})
})).merge()
//对于每一个按钮都对selectedButton进行订阅,根据它是否是当前选中的按钮绑定isSelected属性(map闭包判断按钮是否是选中的按钮,返回一个Bool值,并将Bool值绑定到UIButton的isSelected属性上)
for button in btns {
selectButton.map {
$0 == button
}.bind(to: button.rx.isSelected).disposed(by: disposeBag)
}
}
这样我们就很容易的实现了想要的洗过,看着代码更加简洁、可读性更高
在开发中,我们可能还会遇到UISwitch控制UIButton是否可以点击情况
这个使用RxSwift会更加直观
func isEnabled() {
// 创建UISwitch
let switchBtn: UISwitch = UISwitch.init(frame: CGRect(x: 100, y: 200, width: 50, height: 50))
self.view.addSubview(switchBtn)
//获取到UISwitch的isOn属性通过bind绑定到UIbutton的isEnabled属性上,这样当我通过isOn来决定UIbutton是否可以使用
switchBtn.rx.isOn
.bind(to: self.clickBtn.rx.isEnabled)
.disposed(by: disposeBag)
}
到此RxSwift下的UIButton就介绍完毕了,其实还有很多,这里就是介绍一下基本的使用。下面附上UIButton的所有使用方法以及效果图
import UIKit
import RxSwift
import RxCocoa
class ButtonVC: ViewController {
@IBOutlet weak var RxSwiftButton: UIButton!
@IBOutlet weak var oneButton: UIButton!
@IBOutlet weak var twoButton: UIButton!
@IBOutlet weak var threeButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
RxSwiftButton.rx.tap.subscribe(onNext: { [weak self] in
self!.showMessage("RxSwift写法被点击")
self!.bindToButton()
}).disposed(by: disposeBag)
moreButton()
}
@IBAction func ordinaryAction(_ sender: Any) {
showMessage("普通版本的点击事件")
}
//显示消息提示框
func showMessage(_ text: String) {
let alertController = UIAlertController(title: text, message: nil, preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}
// MARK:- Button 内容 图片的绑定
func bindToButton() {
//普通的文本绑定
let timer = Observable.interval(1, scheduler: MainScheduler.instance)
timer.map { return "计算时间:\($0)" }.bind(to: RxSwiftButton.rx.title()).disposed(by: disposeBag)
// //富文本
// timer.map(bindAttributedTitle(ms:)).bind(to: RxSwiftButton.rx.attributedTitle()).disposed(by: disposeBag)
// //绑定图片
// timer.map({
// let string = $0 % 2 == 1 ? "img_operation_success" : "img_operation_failure"
// return UIImage(named: string)!
// }).bind(to: RxSwiftButton.rx.image()).disposed(by: disposeBag)
// //绑定背景图片
// timer.map({
// let string = $0 % 2 == 1 ? "img_operation_success" : "img_operation_failure"
// return UIImage(named: string)!
// }).bind(to: RxSwiftButton.rx.backgroundImage()).disposed(by: disposeBag)
}
// 将数字转成对应的富文本
func bindAttributedTitle(ms: NSInteger) -> NSMutableAttributedString {
let string = String(format: "%0.2d:%0.2d.%0.1d",
arguments: [(ms / 600) % 600, (ms % 600 ) / 10, ms % 10])
//富文本设置
let attributeString = NSMutableAttributedString(string: string)
//从文本0开始6个字符字体HelveticaNeue-Bold,16号
attributeString.addAttribute(NSAttributedString.Key.font,
value: UIFont(name: "HelveticaNeue-Bold", size: 16)!,
range: NSMakeRange(0, 5))
//设置字体颜色
attributeString.addAttribute(NSAttributedString.Key.foregroundColor,
value: UIColor.white, range: NSMakeRange(0, 5))
//设置文字背景颜色
attributeString.addAttribute(NSAttributedString.Key.backgroundColor,
value: UIColor.orange, range: NSMakeRange(0, 5))
return attributeString
}
// MARK: - 见Switch点开关时间绑定到Button的是否能使用事件上
@IBAction func switchAction(_ sender: UISwitch) {
sender.rx.isOn.bind(to: RxSwiftButton.rx.isEnabled).disposed(by: disposeBag)
}
// MARK: - 多个按钮之间的点击事件
func moreButton() {
let btns = [oneButton,twoButton,threeButton].map({$0!})
let selectButton = Observable.from(btns.map({ btn in
btn.rx.tap.map({btn})
})).merge()
for button in btns {
selectButton.map {
$0 == button
}.bind(to: button.rx.isSelected).disposed(by: disposeBag)
}
}
}
下面是本人学习过程自己写的一个demo,感兴趣的小伙伴大家可以下载看一看。
Csdn下载
Gitbub下载
RxSwift的使用(三)