6 API warppers
这个demo就是大体演示了几个UIKit 扩展的一些Reactive 属性
没啥好说的,这边就随便写写了
这边的 <->
的操作符,一开始我还是有点懵逼。
发现在Operators
文件中,是创建的拓展操作符。就是绑定。平常应该用不到。
平时我们UIKit的属性 一般都改成响应式都有3个分类
1 Binder
遵循 ObserverType
协议
UILabel为例
/// Bindable sink for `text` property.
public var text: Binder<String?> {
return Binder(self.base) { label, text in
label.text = text
}
}
text
和 Binder
都是继承Binder
这说这些属性只能是订阅者。不能去发送消息。
只能这样使用
xxx.bind(to: text)
2 ControlEvent
遵循 ControlEventType
协议 上层又是 ObservableType
这说明 这是可订阅的
UIButton 为例
/// Reactive wrapper for `TouchUpInside` control event.
public var tap: ControlEvent<Void> {
return controlEvent(.touchUpInside)
}
tap
就是 ControlEvent
类型
看ControlEvent
源码,克直接订阅 也可以转化为 Observable
订阅
public func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == E {
return _events.subscribe(observer)
}
/// - returns: `Observable` interface.
public func asObservable() -> Observable<E> {
return _events
}
3 ControlProperty
遵循ControlPropertyType
协议 上层是 ObservableType, ObserverType
以UITextField
为例
/// Reactive wrapper for `text` property.
public var text: ControlProperty<String?> {
return value
}
textfiled的text 既可以发送休息,也可以接受消息
总结的来说,还是ObservableType, ObserverType
一般来说ObserverType
都是那些显示的属性去遵循。ObservableType
都是一些事件属性和与用户有交互的一些属性(例如textfiled的text)去遵循
7 Calculator
哇 这个真是看的头皮发麻 溜了 有时间补上
8 ImagePicker
这个demo 重点就是扩展了创建了imagePicker的过程
我们来看vc 中的代码
cameraButton.rx.tap
.flatMapLatest { [weak self] _ in //1 tap -> picker
return UIImagePickerController.rx.createWithParent(self) { picker in
picker.sourceType = .camera
picker.allowsEditing = false
} //2 -> info
.flatMap { $0.rx.didFinishPickingMediaWithInfo }
.take(1)
}
.map { info in //3 info map image
return info[UIImagePickerControllerOriginalImage] as? UIImage
}
.bind(to: imageView.rx.image) //4 binder
.disposed(by: disposeBag)
tap -> create picker -> image -> binder
这里flatMapLatest
我感觉没有必要 因为创建picker信号序列,应该不存在信号延迟的问题。这里我感觉可以换成flatMap
这里重点就是tap 的event 信号 转换为 picker序列
extension Reactive where Base: UIImagePickerController {
static func createWithParent(_ parent: UIViewController?, animated: Bool = true, configureImagePicker: @escaping (UIImagePickerController) throws -> () = { x in }) -> Observable<UIImagePickerController> {
return Observable.create { [weak parent] observer in
let imagePicker = UIImagePickerController() //
let dismissDisposable = imagePicker.rx
.didCancel
.subscribe(onNext: { [weak imagePicker] _ in
guard let imagePicker = imagePicker else {
return
}
dismissViewController(imagePicker, animated: animated)
})
do {
try configureImagePicker(imagePicker)
}
catch let error {
observer.on(.error(error))
return Disposables.create()
}
//
guard let parent = parent else {
observer.on(.completed)
return Disposables.create()
}
parent.present(imagePicker, animated: animated, completion: nil)
observer.on(.next(imagePicker))
return Disposables.create(dismissDisposable, Disposables.create {
dismissViewController(imagePicker, animated: animated)
})
}
}
}
代码 我们来一步一步看
1 方法名
static func createWithParent(_ parent: UIViewController?, animated: Bool = true, configureImagePicker: @escaping (UIImagePickerController) throws -> () = { x in }) -> Observable<UIImagePickerController>
这个configureImagePicker 差点看懵逼了 其实就是给了一个空实现。没什么作用
1 创建imagepicker
2 订阅取消按钮 dismiss
3 配置 imagepicker
4 发送imagepicker
5 present
6 返回Disposables