860901694207a6043f47347689276862
跟我学RxSwift06 - 观察者(下):自定义可绑定属性

上节我们讲了什么是观察者以及观察者的创建和简单使用。本节我们继续讲观察者,讲讲如何自定义可绑定属性

一、自定义可绑定属性

UI 控件是我们开发中必不可少的,界面的绘制都仰仗它。比如 UILabelUIImageViewUIViewUIButtonUITableView等等。有时我们想让 UI 控件创建出来后默认就有一些观察者,而不必每次都为它们单独去创建观察者。这时候就需要我们自定义可绑定属性了。下面我通过一个简单的例子来为大家讲解:

需求:根据事件值自动改变 UILabel 控件文字大小

方式一:通过对 UI 类进行扩展

我们通过对 UILabel 进行扩展,增加了一个 fontSize 可绑定属性。

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {

     weak var label: UILabel!

    let disposeBag = DisposeBag()

    override func viewDidLoad() {

        // Observable序列(每隔0.5秒钟发出一个索引数)
        let observable = Observable<Int>.interval(0.5, scheduler: MainScheduler.instance)
        observable
            .map { CGFloat($0) }
            .bind(to: label.fontSize) // 根据索引数不断变放大字体
            .disposed(by: disposeBag)
    }
}

// UILabel扩展
extension UILabel {
    public var fontSize: Binder<CGFloat> {
        return Binder(self) { label, fontSize in
            label.font = UIFont.systemFont(ofSize: fontSize)
        }
    }
}

我们可以看到,随着序列数的不断增长,标签文字也不断的变大。运行效果大家可以自己动手尝试。

方式二:通过对 Reactive 类进行扩展

既然使用了 RxSwift,那么更规范的写法应该是对 Reactive 进行扩展。这里同样是给 UILabel 增加了一个 fontSize 可绑定属性。需要注意的是 这种方式下,我们绑定属性时要写成 label.rx.fontSize

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {

     weak var label: UILabel!

    let disposeBag = DisposeBag()

    override func viewDidLoad() {

        // Observable序列(每隔0.5秒钟发出一个索引数)
        let observable = Observable<Int>.interval(0.5, scheduler: MainScheduler.instance)
        observable
            .map { CGFloat($0) }
            .bind(to: label.rx.fontSize) // 根据索引数不断变放大字体
            .disposed(by: disposeBag)
    }
}

extension Reactive where Base: UILabel {
    public var fontSize: Binder<CGFloat> {
        return Binder(self.base) { label, fontSize in
            label.font = UIFont.systemFont(ofSize: fontSize)
        }
    }
} 

OK,自定义可绑定属性是不是非常简单?大家可以举一反三,比如背景颜色、按钮点击、富文本。。。

二、RxSwift 自带的可绑定属性(UI 观察者)

RxSwift 已经为我们提供许多常用的可绑定属性。比如 UILabel 就有 textattributedText 这两个可绑定属性。

import RxSwift
import UIKit

extension Reactive where Base: UILabel {

    /// Bindable sink for `text` property.
    public var text: Binder<String?> {
        return Binder(self.base) { label, text in
            label.text = text
        }
    }

    /// Bindable sink for `attributedText` property.
    public var attributedText: Binder<NSAttributedString?> {
        return Binder(self.base) { label, text in
            label.attributedText = text
        }
    }

}

那么上文那个定时显示索引数的样例,我们其实不需要自定义 UI 观察者,直接使用 RxSwift 提供的绑定属性即可。

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {

     weak var label: UILabel!

    let disposeBag = DisposeBag()

    override func viewDidLoad() {

        // Observable序列(每隔1秒钟发出一个索引数)
        let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
        observable
            .map { "当前索引数:\($0 )"}
            .bind(to: label.rx.text) // 收到发出的索引数后显示到label上
            .disposed(by: disposeBag)
    }
}

OK,今天的内容就到此为止,祝大家学习愉快。 每天进步一点点,加油!!!
下节预告:跟我学RxSwift07 - Observable & Observer 既是可被监听的序列也是观察者(Subjects、Variables)

© 著作权归作者所有
这个作品真棒,我要支持一下!
RxSwift系列教程, 从多个方面逐一介绍RxSwift的使用方法,不仅会介绍RxSwift的核心内容: 1. ...
0条评论
top Created with Sketch.