Live Demonstration
Example
To run the example project
pod try TableviewPaginator
Installation
CocoaPods
TableviewPaginator is available through CocoaPods. To install
it, simply add the following line to your Podfile
:
pod 'TableviewPaginator'
Carthage
TableviewPaginator is available throguh Carthage, specify it in your Cartfile
:
github "ratulSharker/TableviewPaginator" ~> 0.1.0
Usage
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)
tableviewPaginator?.initialSetup()
}
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) {
tableviewPaginator?.scrollViewDidScroll(scrollView)
}
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)
}
tableviewPaginator?.partialDataFetchingDone()
yourTableView.reloadData()
}
}
Here the dataCount
parameter denoting the newly added number of data, more precisely newly added number of rows.
Tips
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 passedpaginator
object for identifying which paginator is calling this delegate method. In that case user===
Identity Operators to check for reference equality.- Whenever you want to know that any data fetching is running or not use
YOUR_PAGINATOR.state.dataFetchingRunning
. ThisBool
will let you know that status. To check that all the data (all the pages) useYOUT_PAGINATOR.state.allDataFetchingCompleted
thisBool
. To know about the current offset usestate.offset
.
Author
License
TableviewPaginator is available under the MIT license. See the LICENSE file for more info.