一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情。
- 本文主要介绍下一些常用的UI控件和交互应用说明
1. 常用的UI控件
1.1 button
self.button.rx.tap
.subscribe(onNext: { () in
print("点击来了")
})
.disposed(by: disposeBag)
对于button
默认就是tap
,当然我们也可以使用controlEvent
来制定我们想要点击事件
self.button.rx.controlEvent(.touchUpOutside)
.subscribe(onNext: { () in
print("点击来了")
}) .disposed(by: disposeBag)
也可以我们手动创建
Observable<String>.of("sss")
.bind(to: self.button.rx.title())
.disposed(by: disposeBag)
对于我们的button的标题,图片,背景
和富文本标题都做了拓展
绑定我们button标题
self.textFiled.rx.text
.bind(to: self.button.rx.title(for: .normal))
.disposed(by: disposeBag)
对我们的系统设置值的方法进行了包装,转换为Binder<T?>
类型。
Binder
相当于我们的观察者
,序列发生改变
会调用他的on
方法,这里对于binder
有个特点事件回调发生在我们主队列中,不会发送完成事件,会一直进行监听
。
比如我们监听的序列发生了改变则进行调用我们外面设置的闭包
从而更新了我们的UI,对于setImage
和setBackgroundImage
,attributedTitle
都是类似。
1.2 TextField
textField
比较常用,比如监听我们的输入框的值
self.textFiled.rx.text.orEmpty
.subscribe(onNext: { (text) in
print(text)
})
.disposed(by: disposeBag)
这里使用.orEmpty
表示可以为空,nil
的时候显示为“”
输入框实时显示到我们的展示框,做到联动
self.textFiled.rx.text
.bind(to: self.button.rx.title())
.disposed(by: disposeBag)
self.textFiled.rx.text.orEmpty
.bind(to: self.label.rx.text)
.disposed(by: disposeBag)
当然我们可以用做一些条件的判断,比如我们常用的登陆输入框位数判断,是否按钮可以点击
let usernameVaild = self.textFiled.rx.text.orEmpty
.map { (text) -> Bool in
return text.count >= 6
}
usernameVaild.bind(to: self.button.rx.isEnabled)
.disposed(by: disposeBag)
这里记录下有的时候我们主动赋值,但是确却无法响应rx的订阅
self.textFiled.rx.text.orEmpty
.subscribe(onNext: { (text) in
print(text)
})
.disposed(by: disposeBag)
self.textFiled.text = "hello"
没有订阅,我们看下关于textfiled
是如何订阅
看下监听的事件
监听的textfield的allEditingEvents
和valueChanged
的事件,我们主动赋值没有触发
的。
self.textFiled.text = "hello"
self.textFiled.sendActions(for: .allEditingEvents)
1.3 scrollerView
scrollView的偏移量
,进行监听
scrollView.rx.contentOffset
.subscribe(onNext: { [weak self](content) in
self?.view.backgroundColor = UIColor.init(red: content.y/255*0.8, green: content.y/255*0.6, blue: content.y/255*0.3, alpha: 1)
})
.disposed(by: disposeBag)
1.4 展示类
上面通常会和我们进行交互
,对于一些展示类的UI,比如我们的label,UIImageView
通常都是观察者类型
self.label.rx.text.onNext("hello")
let imageV = UIImageView()
imageV.rx.image.onNext(nil)
2. 应用
对于我们日常一些开发比如通知,定时器也是进行了封装,方便我们使用
2.1 通知
通知
的话我们使用rx更简单,比如我们监听键盘的消失的通知
NotificationCenter.default.rx.notification(UIResponder.keyboardWillHideNotification)
.subscribe(onNext: { (noti) in
print(noti)
})
.disposed(by: disposeBag)
2.2 定时器
定时器
timer = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)
timer.subscribe(onNext: { (num) in
print(num)
})
.disposed(by: disposeBag)
我们可以直接使用timer
Observable<Int>.timer(DispatchTimeInterval.seconds(0), period: DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
2.3 手势
对于一些手势的监听event
事件
let tap = UITapGestureRecognizer()
self.label.addGestureRecognizer(tap)
self.label.isUserInteractionEnabled = true
tap.rx.event.subscribe(onNext: { (tap) in
print(tap.view as Any)
})
.disposed(by: disposeBag)
2.4 网络请求
网络请求response
let url = URL(string: "https://www.baidu.com")
URLSession.shared.rx.response(request: URLRequest(url: url!))
.subscribe(onNext: { (response,data) in
print(response)
}).disposed(by: disposeBag)
2.5 kvo
kvo
之前也有分析过
self.person.rx.observeWeakly(String.self, "name")
.subscribe(onNext: { (value) in
print(value as Any)
})
.disposed(by: disposeBag)
self.person.rx.observeWeakly(String.self, "name")
.subscribe { (name) in
print(name)
}
.disposed(by: disposeBag)
3. 总结
我们日常的使用交互类
的空间通常会生成一个序列
,因为它是一直变化的比如textField,button
等发生改变产生信号
,我们展示类
的通常是观察者
类型,用于赋值
。她通过发送事件
,调用闭包赋值
。这样我们可以通过bind
关联他们。对于一些没说到的UI通常也是差不多的,后面会单独说下tableView
。