Fix scrollview offset and request crash
This commit is contained in:
parent
6b2230b4ce
commit
ae76c806ae
|
|
@ -67,7 +67,9 @@ public final class PaginationDataLoadingModel<Cursor: ResettableRxDataSourceCurs
|
|||
state = .loadingMore(after: state)
|
||||
}
|
||||
|
||||
requestResult(from: dataSource)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in // to complete load more indicator view animation
|
||||
self?.requestData()
|
||||
}
|
||||
}
|
||||
|
||||
override func onGot(error: Error) {
|
||||
|
|
@ -89,4 +91,8 @@ public final class PaginationDataLoadingModel<Cursor: ResettableRxDataSourceCurs
|
|||
state = .exhausted
|
||||
}
|
||||
}
|
||||
|
||||
private func requestData() {
|
||||
requestResult(from: dataSource)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,12 +60,16 @@ final public class PaginationWrapper<Cursor: ResettableRxDataSourceCursor, Deleg
|
|||
}
|
||||
}
|
||||
|
||||
private var bottom: CGFloat {
|
||||
wrappedView.scrollView.contentSize.height - wrappedView.scrollView.frame.size.height
|
||||
}
|
||||
|
||||
private let disposeBag = DisposeBag()
|
||||
|
||||
private var currentPlaceholderView: UIView?
|
||||
private var currentPlaceholderViewTopConstraint: NSLayoutConstraint?
|
||||
|
||||
private let applicationCurrentyActive = BehaviorRelay(value: true)
|
||||
private let applicationCurrentlyActive = BehaviorRelay(value: true)
|
||||
|
||||
/// Initializer with table view, placeholders container view, cusor and delegate parameters.
|
||||
///
|
||||
|
|
@ -145,9 +149,13 @@ final public class PaginationWrapper<Cursor: ResettableRxDataSourceCursor, Deleg
|
|||
private func onLoadingMoreState(afterState: LoadingState) {
|
||||
if case .error = afterState { // user tap retry button in table footer
|
||||
uiDelegate?.footerRetryViewWillDisappear()
|
||||
wrappedView.footerView = nil
|
||||
addInfiniteScroll(withHandler: false)
|
||||
wrappedView.scrollView.beginInfiniteScroll(true)
|
||||
|
||||
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn, animations: {
|
||||
self.wrappedView.footerView = nil // to avoid jumpy animation
|
||||
}, completion: { _ in
|
||||
self.addInfiniteScroll(withHandler: false)
|
||||
self.wrappedView.scrollView.beginInfiniteScroll(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,8 +205,8 @@ final public class PaginationWrapper<Cursor: ResettableRxDataSourceCursor, Deleg
|
|||
|
||||
retryView.button.rx
|
||||
.controlEvent(.touchUpInside)
|
||||
.asDriver()
|
||||
.drive(retryEvent)
|
||||
.asObservable()
|
||||
.bind(to: retryEvent)
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
uiDelegate?.footerRetryViewWillAppear()
|
||||
|
|
@ -206,8 +214,14 @@ final public class PaginationWrapper<Cursor: ResettableRxDataSourceCursor, Deleg
|
|||
removeInfiniteScroll { scrollView in
|
||||
self.wrappedView.footerView = retryView
|
||||
|
||||
let newContentOffset = CGPoint(x: 0, y: scrollView.contentOffset.y + retryViewHeight)
|
||||
scrollView.setContentOffset(newContentOffset, animated: true)
|
||||
if scrollView.contentOffset.y + retryViewHeight >= self.bottom {
|
||||
let newContentOffset = CGPoint(x: 0, y: scrollView.contentOffset.y + retryViewHeight)
|
||||
scrollView.setContentOffset(newContentOffset, animated: true)
|
||||
|
||||
if #available(iOS 13, *) {
|
||||
scrollView.setContentOffset(newContentOffset, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -303,19 +317,21 @@ final public class PaginationWrapper<Cursor: ResettableRxDataSourceCursor, Deleg
|
|||
|
||||
private func bindViewModelStates() {
|
||||
paginationViewModel.stateDriver
|
||||
.flatMap { [applicationCurrentyActive] state -> Driver<LoadingState> in
|
||||
if applicationCurrentyActive.value {
|
||||
.asObservable()
|
||||
.observeOn(MainScheduler.asyncInstance)
|
||||
.flatMap { [applicationCurrentlyActive] state -> Observable<LoadingState> in
|
||||
if applicationCurrentlyActive.value {
|
||||
return .just(state)
|
||||
} else {
|
||||
return applicationCurrentyActive
|
||||
return applicationCurrentlyActive
|
||||
.asObservable()
|
||||
.filter { $0 }
|
||||
.delay(0.5, scheduler: MainScheduler.instance)
|
||||
.asDriver(onErrorJustReturn: true)
|
||||
.asObservable()
|
||||
.replace(with: state)
|
||||
}
|
||||
}
|
||||
.drive(stateChanged)
|
||||
.bind(to: stateChanged)
|
||||
.disposed(by: disposeBag)
|
||||
}
|
||||
|
||||
|
|
@ -329,13 +345,13 @@ final public class PaginationWrapper<Cursor: ResettableRxDataSourceCursor, Deleg
|
|||
notificationCenter.notification(UIApplication.willResignActiveNotification)
|
||||
.replace(with: false)
|
||||
.asDriver(onErrorJustReturn: false)
|
||||
.drive(applicationCurrentyActive)
|
||||
.drive(applicationCurrentlyActive)
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
notificationCenter.notification(UIApplication.didBecomeActiveNotification)
|
||||
.replace(with: true)
|
||||
.asDriver(onErrorJustReturn: true)
|
||||
.drive(applicationCurrentyActive)
|
||||
.drive(applicationCurrentlyActive)
|
||||
.disposed(by: disposeBag)
|
||||
}
|
||||
}
|
||||
|
|
@ -348,10 +364,10 @@ private extension PaginationWrapper {
|
|||
case .initial:
|
||||
base.onInitialState()
|
||||
|
||||
case .initialLoading(let after):
|
||||
case let .initialLoading(after):
|
||||
base.onLoadingState(afterState: after)
|
||||
|
||||
case .loadingMore(let after):
|
||||
case let .loadingMore(after):
|
||||
base.onLoadingMoreState(afterState: after)
|
||||
|
||||
case let .results(newItems, from, after):
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ open class RxNetworkOperationModel<LoadingStateType: NetworkOperationState>: Net
|
|||
func requestResult(from dataSource: DataSourceType) {
|
||||
currentRequestDisposable = dataSource
|
||||
.resultSingle()
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribe(onSuccess: { [weak self] result in
|
||||
self?.onGot(result: result, from: dataSource)
|
||||
}, onError: { [weak self] error in
|
||||
|
|
|
|||
Loading…
Reference in New Issue