Awesome Open Source
Awesome Open Source

CI Status codebeat badge Version Carthage compatible License Platform Xcode Swift

Live Demonstration


To run the example project

pod try TableviewPaginator



TableviewPaginator is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'TableviewPaginator' 

TableviewPaginator is available throguh Carthage, specify it in your Cartfile:

github "ratulSharker/TableviewPaginator" ~> 0.3.3

Add the TableviewPaginator.swift file to your Xcode project and you are good to go.


Step 1: Import the TableviewPaginator module in swift.

import TableviewPaginator

Step 2: Take a reference to TableviewPaginator (say tableviewPaginator) into your controller. This example assumes that you use UIViewController as your controller.

private var tableviewPaginator: TableviewPaginator?

Step 3: Initialize the tableviewPaginator in your viewDidLoad callback. Note that, before doing initialSetup method call, initialize your viewModel classes (from where you supply the data to view controller).

override func viewDidLoad() {
  // do all you model setup before initializing the tableviewPaginator
  tableviewPaginator = TableviewPaginator.init(paginatorUI: self, delegate: self)

Step 4: Now we have to implement two protocol TableviewPaginatorUIProtocol & TableviewPaginatorProtocol. TableviewPaginatorUIProtocol is responsible for specifying the tableview to working on and some other UI stuffs. TableviewPaginatorProtocol is responsible for let you know when to load and which data segment to load. The reason behind putting them inside of two different protocol is that, you may introduce a new class which is responsible for implementing TableviewPaginatorUIProtocol and keep the TableviewPaginatorProtocol implementation in your controller.

Implementing TableviewPaginatorUIProtocol

extension YourViewController: TableviewPaginatorUIProtocol {
    func getTableview(paginator: TableviewPaginator) -> UITableView {
        return yourTableview

    func shouldAddRefreshControl(paginator: TableviewPaginator) -> Bool {
        return true

    func getPaginatedLoadMoreCellHeight(paginator: TableviewPaginator) -> CGFloat {
        return 44

    func getPaginatedLoadMoreCell(paginator: TableviewPaginator) -> UITableViewCell {
        if let cell = yourTableview.dequeueReusableCell(withIdentifier: "YOUR_LOAD_MORE_CELL_IDENTIFIER") as? YourLoadMoreCell {
            // customize your load more cell
            // i.e start animating the UIActivityIndicator inside of the cell
            return cell
        } else {
            return UITableViewCell.init()

    func getRefreshControlTintColor(paginator: TableviewPaginator) -> UIColor {
        return yourColorOfChoice

Implementing TableviewPaginatorProtocol

extension YourViewController: TableviewPaginatorProtocol {
    func loadPaginatedData(offset: Int, shouldAppend: Bool, paginator: TableviewPaginator) {
        // call your data populating method here
        // i.e given below
        yourViewModel?.fetchData(offset: offset, limit: yourDataFetchLimit, shouldAppend: shouldAppend)

Step 5: Now you have to call some methods from UITableViewDelegate, UITableViewDataSource & your data fetched callbacks.

inside of heightForRowAt call heightForLoadMore as following.

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // if the current indexPath should show the Load more cell
    // then heightForLoadMore will return a valid height
    // height provided in the TableviewPaginatorUIProtocol
    if let height = tableviewPaginator?.heightForLoadMore(cell: indexPath) {
        return height

    return yourCellHeight

inside of scrollViewDidScroll will look like follwoing. scrollViewDidScroll is inherited from UIScrollViewDelegate.

override func scrollViewDidScroll(_ scrollView: UIScrollView) {

inside of numberOfRowsInSection, call rowsIn as following

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let yourCurrentNumberOfRows
    let tableviewPagiantorLoadeMoreCells = (tableviewPaginator?.rowsIn(section: section) ?? 0)
    return yourCurrentNumberOfRows + tableviewPagiantorLoadeMoreCells

inside of cellForRowAt, call cellForLoadMore as following

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if let cell = tableviewPaginator?.cellForLoadMore(at: indexPath) {
        return cell

    // write your own cell returning logic

All of this implementation was very straight forward. The last task is to, let tableviewPaginator know that you have successfully completed the data fetching. This requires a function call from your data fetch completion delegate / code block. Here i assume that, you provide a delegate by the viewModel & implement that delegate in your viewController. There must be a method saying that dataFetched. Implemetation will look like following

extension YourViewController: YourViewModelProtocol {
    func dataFetched(success: Bool, dataCount: Int) {
        if success {
            tableviewPaginator?.incrementOffsetBy(delta: userCount)



Here the dataCount parameter denoting the newly added number of data, more precisely newly added number of rows.


  1. TableviewPaginator is a pure swift class. If you intend to use multiple paginator in the single view controller (use case like, showing two different tableview in a single view controller, switching between them using the Segmented control) you may want to check against the passed paginator object for identifying which paginator is calling this delegate method. In that case user === Identity Operators to check for reference equality.
  2. Whenever you want to know that any data fetching is running or not use YOUR_PAGINATOR.state.dataFetchingRunning. This Bool will let you know that status. To check that all the data (all the pages) use YOUT_PAGINATOR.state.allDataFetchingCompleted this Bool. To know about the current offset use state.offset.


[email protected]


TableviewPaginator is available under the MIT license. See the LICENSE file for more info.

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Swift (95,353
Pagination (879
Uitableview (339
Related Projects