Swift - Creating a Paginated List in Storyboard

This article explains what paginated lists are and discusses the implementation of paginated lists in Swift applications that use Storyboard.

What are Paginated Lists and Why use them?

Handling large sets of data can be a challenging task on mobile phones. Suppose you are browsing through an e-commerce application and there are millions of products sold on the platform, loading and rendering these products at once in one list is a task that is close to impossible as there is a lot of data attached to a single product and there is a large list of such products. Such a task would cause the smartphone to slow down as the app would be consuming and demanding more resources than the phone can offer.

This brings us to our topic at hand, that is, Paginated Lists. Large lists are broken down into multiple smaller chunks of data, called Pages. Pages often contain a very small amount of data (around 10-20 products, if we consider the above example) and this allows the application to run smoothly as the backend response time for getting this data would be very low and the phone would not have excess data to process.

The application would request the first page of data from the backend and render that data. The backend response would contain an identifier which would be used to request the next page of data. As the user scrolls and reaches the end of the product list from the first page, the application would send a request for the next page and append the new data at the end of the list. This would provide a continuous scrolling experience to the user while keeping the application fast.

Paginated Lists in Swift

We need to first add an UIContainerView in the storyboard and assign the PaginatedListViewController as its View Controller. You can either use an UITableView or an UICollectionView for rendering your list (We will be using an UICollectionView in our example.) We will add a Collection view in our new container and assign a name to the segue identifier.

Img1 Screenshot-2022-07-22-at-2.20.18-PM Screenshot-2022-07-22-at-2.21.08-PM

We will be creating a UIViewController to handle the paginated list and we will pass an object to configure the list. This ViewController will act as the Datasource and Delegate for your list.

struct ListConfig {
    var cellNibName: String
    var cellReuseIdentifier:String
    var apiCall: (_ nextPageIdentifier: String?, @escaping (_ data: 
            ListApiData?, _ error: String?) -> Void) -> Void
}

We will maintain an object containing an array of item ids and the paginationIdentifier string that will identify the next page.

struct ListApiData {
    var ids: [Int]? = []
    var paginationIdentifier: String? = nil
}

We will request the first page and store the paginationIdentifier received in the response and append the data received in our ids array.  

func getPageData(){
    if self.isMoreDataLoading == false {
        self.isMoreDataLoading = true
        listConfig?.apiCall(listData.paginationIdentifier) { apiData, error in
            if let _ = error {
                return
            }
            guard let data = apiData else { return }
            
            self.isMoreDataLoading = false
            if let nextPageId = data.paginationIdentifier {
                self.listData.paginationIdentifier = nextPageId
            }else{
                self.listData.paginationIdentifier = nil
            }

            //Append new data to the list.
            if let ids = data.ids {
                self.listData.ids?.append(contentsOf: ids)
            }
            DispatchQueue.main.async {
                self.paginatedList.reloadData()
            }
        }
    }
}

Next, we need to define the index of the element, which on render, triggers the next page request. This can be done inside the willDisplay delegate method of collectionView.

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        
    //If the list has scrolled to the last offset element.
    if (indexPath.row == listData.ids!.count - PAGINATION_OFFSET_ELEMENT ) {
        //Load more data & reload your collection view
        getPageData()
    }
}

Conclusion

Pagination is one of the best methods to display a large set of data and it can be achieved fairly easily in Swift projects. You can refer to the full code below for the implementation and integration from another view controller with configurations.

Harsh Siriah

Harsh Siriah

Hi, I'm Harsh! A geek with a love for dogs & mobiles.
Pune, India