Last active
July 13, 2017 09:09
-
-
Save mosluce/f739eef2c8eb59c66d1fff3061933aae to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let disposeBag = DisposeBag() | |
// 模擬 indicator 顯示/隱藏狀態 | |
let indicator = Variable(false) | |
// 按鈕 | |
lazy var loginButton: UIButton = { | |
let button = UIButton(type: .system) | |
button.tintColor = UIColor.red | |
button.setTitle("登入", for: .normal) | |
return button | |
}() | |
//... | |
// 依據是否正在讀取中來改變按鈕狀態 | |
self.indicator.asObservable().map{ !$0 }.bind(to: loginButton.rx.isEnabled).disposed(by: disposeBag) | |
// 按鈕點按 Observer | |
let t = self.loginButton.rx.tap | |
// Xcode 中跟上面連著寫會沒有提示...所以這邊特別用 t 來放 tap | |
t.flatMap { [weak self] () -> Observable<Void> in | |
print(1) | |
self?.indicator.value = true | |
// 5 秒後繼續 | |
return Observable<Void>.just().delay(5, scheduler: MainScheduler.instance) | |
}.subscribe(onNext: {[weak self] () in | |
print(2) | |
self?.indicator.value = false | |
}).disposed(by: disposeBag) |
self.loginButton.rx.tap
.asDriver()
.map { _ in true }
.drive(self.indicator)
.disposed(by: disposeBag)
self.loginButton.rx.tap
.asObservable()
.flatMapLatest { _ in
return Observable<Void>.just().delay(5, scheduler: MainScheduler.instance)
}
.asDriver { _ in .never() } // 有 error 的話丟 .empty 會有 complete 訊號出來,這個按鈕就會被 disposed 而無法再按了,所以丟 .never()
.map { _ in false }
.drive(self.indicator)
.disposed(by: disposeBag)
只有人腦 compiler ,
感覺後半段這樣寫會比較乾淨
@vc7 原來如此~瞭解!
@vc7 可以請問一下asDriver的用途跟用法嗎?
@yoxisem544
從範例看起來就是連動 Variable
而不用像我還要寫在 map 或 flatMap 裡面
asDriver
是屬於 RxCocoa 的一部分,是獨立於 RxSwift 核心之外的外掛類型的東西
為了方便操作 UI ,而特化出幾個特點
- 會在主執行緒上執行。用 Observable 的話,就必須自己切換
- 不會 failed 、沒有
onError
事件,這樣在 binding 的時候就不會那麼麻煩。 開發階段 bind 碰到 onError 會 crash ...
比較能夠體會出的東西是這些,更詳細的官方文件有寫
我個人的建議是不要在 ViewModel 裡面用 Driver
@vc7 感謝講解~~剛剛有翻一下官方文件但看的不是很懂,現在有比較了解一點了
@yoxisem544
補充一個 asDriver 會自動 share ,所以就不用再加 shareReplay(1)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
自動完成壞掉了? XDD要轉成 ObservableType 之後才可以用,
例如
asObservable()
,asDriver()
等等