RxSwift 分页 tableView 靠近底部

RxSwift pagination tableView near bottom

所以我正在我的应用程序中进行分页,但我遇到了一些奇怪的行为:

class ViewController: UIViewController {
   func bindRx() {
    btn.rx
        .tap
        .bind(to: viewModel.searchButtonTapped)
        .disposed(by: disposeBag)
    
    searchField.rx
        .text
        .orEmpty
        .bind(to: viewModel.searchText)
        .disposed(by: disposeBag)
    
    searchField.rx
        .searchButtonClicked
        .bind(to: viewModel.searchButtonTapped)
        .disposed(by: disposeBag)
    
    viewModel.itemsDriver.drive(tableView.rx.items) { (tableView, row, element) -> UITableViewCell in
        
        switch element {
        case .post(model: let vm):
            let cell = tableView.dequeueReusableCell(withIdentifier: "PostTableViewCell") as! PostTableViewCell
            cell.config(viewModel: vm)
            return cell
            
        case .promotion(title: _):
            let cell = tableView.dequeueReusableCell(withIdentifier: "PromotionTableViewCell") as! PromotionTableViewCell
            return cell
        }
        
    }.disposed(by: disposeBag)
    
    viewModel
        .isLoading
        .drive(tableView.rx.animation)
        .disposed(by: disposeBag)
    
    tableView.rx
        .modelSelected(CellType.self)
        .bind(to: viewModel.selectedCell)
        .disposed(by: disposeBag)
    
    
 //        tableView.rx
  //            .willDisplayCell
  //            .subscribe(onNext: { cell, indexPath in
 //                let lastItem = self.viewModel.counter - 1
  //                if indexPath.row == lastItem {
 //                    self.viewModel.loadMore.accept(())
  //                }
 //            })
 //            .disposed(by: disposeBag)
    
    tableView.rx
        .reachedBottom()
        .debug("botoom!!!!!!!!!")
        .bind(to: self.viewModel.loadMore)
        .disposed(by: disposeBag)
}

}

public extension Reactive where Base: UIScrollView {
/**
 Shows if the bottom of the UIScrollView is reached.
 - parameter offset: A threshhold indicating the bottom of the UIScrollView.
 - returns: ControlEvent that emits when the bottom of the base UIScrollView is reached.
 */
func reachedBottom(offset: CGFloat = 0.0) -> ControlEvent<Void> {
    let source = contentOffset.map { contentOffset in
        let visibleHeight = self.base.frame.height - self.base.contentInset.top - self.base.contentInset.bottom
        let y = contentOffset.y + self.base.contentInset.top
        let threshold = max(offset, self.base.contentSize.height - visibleHeight)
        return y >= threshold
    }
    .distinctUntilChanged()
    .filter { [=11=] }
    .map { _ in () }
    return ControlEvent(events: source)
}

}

final class PostsViewModel {

init(networking: Networking = Networking()) {
    self.networking = networking
    
    
    
    searchButtonTapped.subscribe(onNext: { [weak self] value in
        self?.page = 0
        self?.counter = 0
        self?.loadMore.accept(())
    }).disposed(by: disposeBag)
    
    searchText.subscribe(onNext: { [weak self] value in
        self?.params.updateValue(value, forKey: "search_query")
    }).disposed(by: disposeBag)
    
    
    let load = loadMore.scan(0) { (value, _) -> Int in
        self.page = self.page + 1
        self.params.updateValue(self.page, forKey: "page")
        return value + 1
    }
            
   let test = load
        .flatMapLatest { page in
            self.networking.preformNetworkTaskGet(
                endPoint: Api.get,
                type: Posts.self,
                methodType: .get,
                param: self.params)
              //  .debug("call1 ")
        }
    .scan(into: [Post]()) { current, items in
        current.append(contentsOf: items.data)
        self.counter = current.count
        }
  //  .debug(" all  ")
    .share()
    
    let vm = test.map {
        self.postsToCellViewModel(posts: [=12=])
    }
    
   
    
    itemsDriver = vm
        .map { [=12=] }
        .asDriver(onErrorJustReturn: [])
        .debug("2")
}

 struct Networking: NetworkType {
func downloadImage(url: String) -> Observable<UIImage> {
    return Observable<UIImage>.create { (observer) -> Disposable in
            AF.request(url).response{ response in
                print(response)
                switch response.result {
                case .success(let responseData):
                    observer.onNext(UIImage(data: responseData!)!)
                case .failure(let error):
                    observer.onError(error)
                }
            }
        return Disposables.create()
    }
}


func preformNetworkTaskGet<T: Codable>(endPoint: EndpointType, type: T.Type, methodType: MethodsType, param: [String : Any]?) -> Observable<T> {
    return Observable<T>.create { (observer) -> Disposable in
        if let url = endPoint.baseURL.appendingPathComponent(endPoint.path).absoluteString.removingPercentEncoding {
            AF.request(url, method: methodType.method, parameters: param, encoding: URLEncoding.default).responseJSON  { (response) in
                switch response.result {
                case .failure(let error):
                    observer.onError(error)
                case .success(_):
                    if let data = response.data {
                        let response = Response.init(data: data)
                        if let decode = response.decode(type) {
                            observer.onNext(decode)
                        } else {
                            observer.onError(NSError())
                        }
                    }
                }
            }
        }
        return Disposables.create()
    }
}

}

第一次网络调用后,我将进入 if 并触发 self.viewModel.loadMore.accept(()),无需任何滚动。 有什么想法吗?

您可以简单地跳过 reachedBottom Observable 的第一个下一个事件...

tableView.rx.reachedBottom().skip(1)