Closed vjujjavarapu-zz closed 8 years ago
Hey @vjujjavarapu!
I think the Github repository search example does a great job of detecting when a tableView reaches the bottom (bottom - 20pts in the example's case) of its content.
Check out https://github.com/ReactiveX/RxSwift/blob/master/RxExample/RxExample/Examples/GitHubSearchRepositories/GitHubSearchRepositoriesViewController.swift#L45, and the entire example for that matter, and come back with any questions you have 👍
static let startLoadingOffset: CGFloat = 20.0
static func isNearTheBottomEdge(contentOffset: CGPoint, _ tableView: UITableView) -> Bool {
return contentOffset.y + tableView.frame.size.height + startLoadingOffset > tableView.contentSize.height
}
let loadNextPage = tableView.rx_contentOffset
.flatMap { offset in
ViewController.isNearTheBottomEdge(offset, tableView)
? Observable.just()
: Observable.empty()
}
This method is not called at all even after doing
tableView.rx_setDelegate(self)
.addDisposableTo(disposeBag)
Hi @vjujjavarapu ,
you need to call one of subscribe
family of methods. You have just created sequence definition.
i just followed your example GitHubSearchRepositories can you please specify which subscribe are you talking about in this file.
class GitHubSearchRepositoriesViewController: ViewController, UITableViewDelegate {
static let startLoadingOffset: CGFloat = 20.0
static func isNearTheBottomEdge(contentOffset: CGPoint, _ tableView: UITableView) -> Bool {
return contentOffset.y + tableView.frame.size.height + startLoadingOffset > tableView.contentSize.height
}
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Repository>>()
override func viewDidLoad() {
super.viewDidLoad()
let tableView = self.tableView
let searchBar = self.searchBar
dataSource.configureCell = { (_, tv, ip, repository: Repository) in
let cell = tv.dequeueReusableCellWithIdentifier("Cell")!
cell.textLabel?.text = repository.name
cell.detailTextLabel?.text = repository.url
return cell
}
dataSource.titleForHeaderInSection = { dataSource, sectionIndex in
let section = dataSource.sectionAtIndex(sectionIndex)
return section.items.count > 0 ? "Repositories (\(section.items.count))" : "No repositories found"
}
let loadNextPageTrigger = tableView.rx_contentOffset
.flatMap { offset in
GitHubSearchRepositoriesViewController.isNearTheBottomEdge(offset, tableView)
? Observable.just()
: Observable.empty()
}
let searchResult = searchBar.rx_text.asDriver()
.throttle(0.3)
.distinctUntilChanged()
.flatMapLatest { query -> Driver<RepositoriesState> in
if query.isEmpty {
return Driver.just(RepositoriesState.empty)
} else {
return GitHubSearchRepositoriesAPI.sharedAPI.search(query, loadNextPageTrigger: loadNextPageTrigger)
.asDriver(onErrorJustReturn: RepositoriesState.empty)
}
}
searchResult
.map { $0.serviceState }
.drive(navigationController!.rx_serviceState)
.addDisposableTo(disposeBag)
searchResult
.map { [SectionModel(model: "Repositories", items: $0.repositories)] }
.drive(tableView.rx_itemsWithDataSource(dataSource))
.addDisposableTo(disposeBag)
searchResult
.filter { $0.limitExceeded }
.driveNext { n in
showAlert("Exceeded limit of 10 non authenticated requests per minute for GitHub API. Please wait a minute. :(\nhttps://developer.github.com/v3/#rate-limiting")
}
.addDisposableTo(disposeBag)
// dismiss keyboard on scroll
tableView.rx_contentOffset
.subscribe { _ in
if searchBar.isFirstResponder() {
_ = searchBar.resignFirstResponder()
}
}
.addDisposableTo(disposeBag)
// so normal delegate customization can also be used
tableView.rx_setDelegate(self)
.addDisposableTo(disposeBag)
// activity indicator in status bar
// {
GitHubSearchRepositoriesAPI.sharedAPI.activityIndicator
.drive(UIApplication.sharedApplication().rx_networkActivityIndicatorVisible)
.addDisposableTo(disposeBag)
// }
}
// MARK: Table view delegate
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 30
}
deist {
// I know, I know, this isn't a good place of truth, but it's no
self.navigationController?.navigationBar.backgroundColor = nil
}
}
I just want to know which part of this triggers and modifies or changes the loadNextPageTrigger! Thank you!
Try doing something like
loadNextPage.subscribe(onNext: { print("the table view is near the bottom!") })
@AndrewSB Thank you for your reply. However can you suggest a way that this prints only once. Or Rather i want to subscribe only once. This one is printing "the tableview is near the bottom!" atleast 10 times. I just want to print it only once .
that's because you're subscribing to the tableView's contentOffset
. You can try something like .take(1)
, .distinctUntilChanged
, or .debounce
to only fire the event once 😄
Thank you :-)
On Sat, Oct 8, 2016 at 7:27 PM Andrew Breckenridge notifications@github.com wrote:
that's because you're subscribing to the tableView's contentOffset. You can try something like .distinctUntilChanged, or .debounce to only fire the event once 😄
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ReactiveX/RxSwift/issues/926#issuecomment-252454152, or mute the thread https://github.com/notifications/unsubscribe-auth/AJy_-Ef25W25sFh6crM8zldQhYdaxSxcks5qyCbngaJpZM4KPKg0 .
However i did not see loadNextPageTrigger Subscribe / take/ distinctUntilChanged or .Debounce in the GitHubSearchRepositories example in the RxExamples in the current repo.
That's because in the example, its fine if the load next page triggers more than once 🙃
Thank you @AndrewSB. You saved my life.
🤗
RxSwift pagination duplicate request duplicate pagination request:
-just remove searchBar from RXExample https://github.com/ReactiveX/RxSwift/tree/master/RxExample/RxExample/Examples/GitHubSearchRepositories
-when scroll to bottom "performSearch" called twice after each other.
Expected outcome:
when scroll to bottom call "performSearch" only once https://stackoverflow.com/questions/53615310/rxswift-pagination-duplicate-request
Could you please suggest an rxswifified way to detect tableview reached the bottom, I have seen the Rx Repo and i could not clearly get it. I know the regular way of scrollviewdelegate and setting the delegate to trigger scrollviewdidscroll, However now i am using RxAlamofire and i get an assertion error delegate has already been set if i do it in the conventional way.