In the context of software, pagination is the process of separating digital content into discrete (separate) pages. This is done so that large amounts of data can be retrieved in parts, rather than all at once which can become very difficult and inefficient as the amount of data increases.
In web applications, pagination is typically implemented by having numbers at the bottom of each page, usually requiring users to click on “next” and “previous” buttons to retrieve the next/previous page of data.
In mobile applications, making a user click on “next” and “previous” buttons at the bottom of a list is not intuitive. So how do we support pagination in mobile apps? The answer is, infinite scrolling!
Infinite scrolling is a design technique whereby users scroll down a list, and content automatically, and continuously loads until there is no more content left to load. This way the user can keep scrolling until they reach the last item on the list, without ever having to manually load more items.
What’s covered:
Infinite Scrolling Basics: Learn how to enhance user experience by loading content dynamically as users scroll.
Key Components: Explore the View, ViewModel, and Backend API and how they work together for seamless pagination.
Implementation Guide: Set up a SwiftUI view with dynamic scrolling, configure a ViewModel for pagination logic, and integrate a loading indicator for user feedback.
What You’ll Learn:
How to implement infinite scrolling in SwiftUI apps using the MVVM architectural pattern.
Techniques for efficient API calls and dynamic data loading.
Practical steps to handle large datasets with a smooth, user-friendly interface.
Equipped with our new understanding of infinite scrolling, let's see how we can use it to implement pagination in our apps using SwiftUI.
Architecture
Below is a high level diagram of the components required to implement infinite scrolling. The arrows indicate the direction data flows.
From the diagram we can see that the view model plays a very important role in implementing infinite scrolling. It is in charge of requesting subsequent pages when appropriate, and it does this by analyzing data provided by the backend API as well as the user's scroll position, as reported by the view.
The next component is the backend API where we get our data from. For the sake of simplicity, I will assume that we already have a backend API which supports pagination. Our only requirements are that it accept a page number in our requests.
Our final component is the view, which thanks to the view model, is actually very simple. All it will do is observe the list of items it must display and notify the view model of it's scroll position.
To learn more about iOS systems design, check out: iOS App System Design: From Concept to Architecture (with example)
SwiftUI View
The primary thing our view code should be able to do is display the list of items and provide our view model with the current scroll position. With SwiftUI, this is surprisingly simple to do, below is the view code.
The first thing the view does is request the first page of data (1) when it is initialized by calling the requestInitialSetOfItems method in the view model. We will look at the view model methods more closely later.
This view code converts the list of items to an enumerated collection (2) which is then iterated by the List view. As the individual individual rows appear, the onAppear modifier is used to pass their index to the view model (3), which will use this information to determine whether it needs to request a subsequent page of data or not.
I decided it was a good idea to give users some indication that more data is loading (4). So I created a simple LoadingView for this purpose. All it does is display a spinner with some text.
To learn more about breaking down SwiftUI views and modeling their state with a view model (MVVM), see: Develop Cleaner SwiftUI Views Using A View Model
View Model
As mentioned earlier, the view model performs the bulk of the infinite scrolling logic. To do that it will need to know what the users current scroll position is, how many items are currently loaded onto the device, and how many total items are available according the the backend API.
Before diving into how the view model will perform its logic, let's see what properties it will need to support infinite scrolling.
Below are the properties necessary in our view model: