RxSwift:使用 rx_refreshing 进行 uirefreshcontrol
RxSwift: using rx_refreshing for uirefreshcontrol
我正在使用 UIRefreshControl
+ Variable
绑定来重新加载数据。
它正在工作,但是,我觉得以下内容不对:
1) 我知道 RXCocoa
扩展中有一个 rx_refreshing
变量,但我无法让它在这种情况下工作。
2) 我绑定了两次答案(这是一个 Variable
数组)。一次当我加载视图控制器时,当 UIRefreshControl
刷新时再次。
3) 我检查 UIRefreshControl
是否刷新的部分看起来真的很尴尬。感觉违背了使用reactive的初衷?
...
let answers: Variable<[Answer]> = Variable([])
override func viewDidLoad() {
loadAnswers()
.shareReplay(1)
.bindTo(answers)
.addDisposableTo(self.disposeBag)
setupRx()
}
func loadAnswers() -> Observable<[Answer]> {
return Network.rxArrayRequest(Spark.Answers)
}
func setupRx() {
rc.rx_controlEvent(.ValueChanged)
.map { _ in !self.rc.refreshing }
.filter { [=11=] == false }
.flatMapLatest { [unowned self] _ in
return self.loadAnswers()
}
.bindTo(answers)
.addDisposableTo(self.disposeBag)
rc.rx_controlEvent(.ValueChanged)
.map { _ in self.rc.refreshing }
.filter { [=11=] == true }
.subscribeNext { [unowned self] _ in
self.rc.endRefreshing()
}
.addDisposableTo(self.disposeBag)
}
...
所以首先,不是实际工作。它只是 似乎 起作用了。在您的代码中,您实际上并没有在调用 rc.endRefreshing()
之前等待网络请求完成。相反,您只是进行网络调用,然后立即调用 endRefreshing()
.
// `rc.rx_controlEvent(.ValueChanged)` only gets called once,
// when the user pulls down.
rc.rx_controlEvent(.ValueChanged) // user pulled down to refresh
.map { _ in !self.rc.refreshing } // !true -> false
.filter { [=10=] == false } // false == false
.flatMapLatest { [unowned self] _ in
return self.loadAnswers() // request answers
}
.bindTo(answers)
.addDisposableTo(self.disposeBag)
rc.rx_controlEvent(.ValueChanged) // user pulled down to refresh
.map { _ in self.rc.refreshing } // true -> true
.filter { [=10=] == true } // true == true
.subscribeNext { [unowned self] _ in
self.rc.endRefreshing() // end refreshing
}
.addDisposableTo(self.disposeBag)
为了解决问题 1
,你是对的,你可以使用 rx_refreshing
来关闭刷新而不是 endRefreshing()
。
为了解决问题 2
,我不认为 Variable
是必要的或有用的,至少在这个例子中是这样。你仍然可以使用它。另外,没有必要在两个地方loadAnswers()
。
为了解决问题 3
,是的,您可以将其简化很多并多使用 Rx
。
这是实际可行的代码,使用 rx_refreshing
,并大大简化了事情:
let initial = Observable<Void>.just(())
let refresh = rc.rx_controlEvent(.ValueChanged).map { _ in () }
let answers = Observable.of(initial, refresh)
.merge()
.flatMapLatest{ _ in self.loadAnswers() }
.shareReplayLatestWhileConnected()
answers
.map { _ in false }
.bindTo(rc.rx_refreshing)
.addDisposableTo(disposeBag)
// also use `answers` to bind to your data source, etc.
我正在使用 UIRefreshControl
+ Variable
绑定来重新加载数据。
它正在工作,但是,我觉得以下内容不对:
1) 我知道 RXCocoa
扩展中有一个 rx_refreshing
变量,但我无法让它在这种情况下工作。
2) 我绑定了两次答案(这是一个 Variable
数组)。一次当我加载视图控制器时,当 UIRefreshControl
刷新时再次。
3) 我检查 UIRefreshControl
是否刷新的部分看起来真的很尴尬。感觉违背了使用reactive的初衷?
...
let answers: Variable<[Answer]> = Variable([])
override func viewDidLoad() {
loadAnswers()
.shareReplay(1)
.bindTo(answers)
.addDisposableTo(self.disposeBag)
setupRx()
}
func loadAnswers() -> Observable<[Answer]> {
return Network.rxArrayRequest(Spark.Answers)
}
func setupRx() {
rc.rx_controlEvent(.ValueChanged)
.map { _ in !self.rc.refreshing }
.filter { [=11=] == false }
.flatMapLatest { [unowned self] _ in
return self.loadAnswers()
}
.bindTo(answers)
.addDisposableTo(self.disposeBag)
rc.rx_controlEvent(.ValueChanged)
.map { _ in self.rc.refreshing }
.filter { [=11=] == true }
.subscribeNext { [unowned self] _ in
self.rc.endRefreshing()
}
.addDisposableTo(self.disposeBag)
}
...
所以首先,不是实际工作。它只是 似乎 起作用了。在您的代码中,您实际上并没有在调用 rc.endRefreshing()
之前等待网络请求完成。相反,您只是进行网络调用,然后立即调用 endRefreshing()
.
// `rc.rx_controlEvent(.ValueChanged)` only gets called once,
// when the user pulls down.
rc.rx_controlEvent(.ValueChanged) // user pulled down to refresh
.map { _ in !self.rc.refreshing } // !true -> false
.filter { [=10=] == false } // false == false
.flatMapLatest { [unowned self] _ in
return self.loadAnswers() // request answers
}
.bindTo(answers)
.addDisposableTo(self.disposeBag)
rc.rx_controlEvent(.ValueChanged) // user pulled down to refresh
.map { _ in self.rc.refreshing } // true -> true
.filter { [=10=] == true } // true == true
.subscribeNext { [unowned self] _ in
self.rc.endRefreshing() // end refreshing
}
.addDisposableTo(self.disposeBag)
为了解决问题 1
,你是对的,你可以使用 rx_refreshing
来关闭刷新而不是 endRefreshing()
。
为了解决问题 2
,我不认为 Variable
是必要的或有用的,至少在这个例子中是这样。你仍然可以使用它。另外,没有必要在两个地方loadAnswers()
。
为了解决问题 3
,是的,您可以将其简化很多并多使用 Rx
。
这是实际可行的代码,使用 rx_refreshing
,并大大简化了事情:
let initial = Observable<Void>.just(())
let refresh = rc.rx_controlEvent(.ValueChanged).map { _ in () }
let answers = Observable.of(initial, refresh)
.merge()
.flatMapLatest{ _ in self.loadAnswers() }
.shareReplayLatestWhileConnected()
answers
.map { _ in false }
.bindTo(rc.rx_refreshing)
.addDisposableTo(disposeBag)
// also use `answers` to bind to your data source, etc.