- Published on
Pagination
- Authors
- Name
- Misiel Rodriguez
- @misiel
As a mobile developer, device resource management is an important constraint to keep in mind as you are building applications and new features. GitHub Followers is an app that allows the user to search up a user and view a list of their followers and tap each follower for a more detailed info screen. However, what if we query for a user and the followers API endpoint returns a list of 1000 followers. Do we really want the user to comb through 1000 different potential collection view cells and wait for a network call to load 1000+ results?
Here is where the user experience concept of Pagination comes into the play.
Pagination
is a data retrieval technique that allows for a large set of data to be received in chunks. Instead of the followers endpoint returning 1000 followers in 1 go, it'll return 100 followers (or any selected number) in batches, waiting for the user to request the next batch usually by scrolling to the bottom of the list and then dragging past it to indicate that they want to make another batch request.
Implementation
To keep track of when a user is at the bottom of the list (collection/table view) and ready to make the next network call, we have to implement the UICollectionViewDelegate
method: scrollViewDidEndDragging()
.
Here's the code for that method:
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
let offsetY = scrollView.contentOffset.y // how far we scrolled down
let contentHeight = scrollView.contentSize.height // height off all collectionView items
let height = scrollView.frame.height // height of screen
// If how far we scrolled from the top is > the height of the content - what's on screen, that means we've reached the bottom of the list and we can call our next batch
if offsetY > contentHeight - height {
guard hasMoreFollowers else { return }
self.page += 1
self.getFollowers(username: self.username, page: self.page)
}
}
There's 3 variables we need that lets us know our placement in the collectionView:
offsetY
: how far we scrolled down in our list
contentHeight
: is the height of the items in the collectionView
height
: is the height of the screen
To know when we're at the bottom of the collectionView and the user is dragging past the bottom, we check to see when offsetY
is greater than (contentHeight - height)
which is the value for the amount of space that items are taking up off screen.
Here's an example:
100 items in a list = a contentHeight of 100
Our screen is a size of 10.
According to our formula, a user has to have scrolled to an offset of 91 (100-10 = 90) to trigger the next pagination call.
When the offset is at 0-90, we are still within the height of content of our collection view. Think about it like this, the height of the screen serves as a padding for the content to be shown in.
When we are an offsetY of 90, the remaining 10 is the last bit of the content and it's all displayed on screen, there is no more content to be shown.
This is the perfect moment for our next batch to be called when the user tries to scroll past this.
Impl. (continuted)
Ok now we know when the user triggers the next pagination call, but how is it exactly that we know how to return the next X amount of results?
Well in the previous code block, we also have the following lines:
guard hasMoreFollowers else { return }
self.page += 1
self.getFollowers(username: self.username, page: self.page)
page
is the variable that we pass in to our network call to the followers api. Here is the documentation for the api endpoint that shows this:
So whenever the user gets to the point where they are scrolling to the next batch, we increment page
and pass the new value to our api endpoint call. However, we only do this if hasMoreFollowers
is true
which gets flipped to false
if the user makes a call and the returned count of the list of followers is less than 100 which is the max amount that we're getting per network call. Less than 100 means there's no point in fetching the next batch because our current batch already has all the remaining followers.
And that's it for pagination!
Thanks for reading!