Swift - RxSwift的使用详解6(观察者2: 自定义可绑定属性)

五、自定义可绑定属性

有时我们想让 UI 控件创建出来后默认就有一些观察者,而不必每次都为它们单独去创建观察者。比如我们想要让所有的 UIlabel 都有个 fontSize 可绑定属性,它会根据事件值自动改变标签的字体大小。

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

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

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    @IBOutlet 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)
    }
}
 
extension UILabel {
    public var fontSize: Binder<CGFloat> {
        return Binder(self) { label, fontSize in
            label.font = UIFont.systemFont(ofSize: fontSize)
        }
    }
}

(2)运行结果如下,随着序列数的不断增长,标签文字也不断的变大。

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

既然使用了 RxSwift,那么更规范的写法应该是对 Reactive 进行扩展。这里同样是给 UILabel 增加了一个 fontSize 可绑定属性。

(注意:这种方式下,我们绑定属性时要写成 label.rx.fontSize

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    @IBOutlet 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)
        }
    }
}

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

(1)其实 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
        }
    }
     
}

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

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    @IBOutlet 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)
    }
}

(3)运行结果如下:

RxSwift使用详解系列
原文出自:www.hangge.com转载请保留原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 前言 在之前用Objective-C语言做项目的时候,我习惯性的会利用MVVM模式去架构项目,在框架Reactiv...
    Tangentw阅读 21,333评论 32 124
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,031评论 19 139
  • **01 ** 那年,我还在读初中。那时候家离学校比较远,坐公交车很麻烦,因此我只好每天五点钟起床,一个人从五点半...
    ETer大卫阅读 2,490评论 2 0
  • 这句话看起来是个悖论,但是吃过几次亏就知道此乃至理名言。 我刚刚上班时也是傲娇的很,工作时间颇喜欢在qq上闲聊,刷...
    大二炜阅读 3,392评论 4 2
  • 我见过最迷醉人心的蓝色,不来自于天空,也不源自于海洋。 未曾去过新疆的人,总爱以漫漫黄沙为它覆上一层神秘的面纱。于...
    吴六一阅读 3,868评论 0 2

友情链接更多精彩内容