iOS Swift RxSwift 的使用(二)

上篇文章呢,我们介绍了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
    }

iOS Swift RxSwift 的使用(二)_第1张图片


其实到这里我们对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)
        }
    }
}

iOS Swift RxSwift 的使用(二)_第2张图片

下面是本人学习过程自己写的一个demo,感兴趣的小伙伴大家可以下载看一看。


Csdn下载

Gitbub下载


RxSwift的使用(三)

 

你可能感兴趣的:(RxSwfit,Swift,iOS)