Last active
May 15, 2019 05:42
-
-
Save shishirthedev/6720e1d1e4f0b5af735182111643ebb5 to your computer and use it in GitHub Desktop.
iOS tableview adapter custom code with pagination and refresh Control....
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
protocol SSAdapterDelegate { | |
func willDisplay(cell: UITableViewCell, indexPath: IndexPath) | |
func didSelected(indexPath: IndexPath) | |
func hasNextPage()->Bool | |
func isLoadingFooterAdded()->Bool | |
func loadMoreData() | |
func refreshTableData() | |
} | |
extension SSAdapterDelegate{ | |
func loadMoreData(){} | |
func didSelected(indexPath: IndexPath){} | |
func hasNextPage()->Bool { return false } | |
func refreshTableData(){} | |
} | |
class SSAdapter<T>: NSObject, UITableViewDelegate, UITableViewDataSource{ | |
var tv: UITableView | |
var cellIdentifier: String | |
var sDelegate: SSAdapterDelegate? | |
var tableData:[T] = [T]() | |
/* Refresh Control doesn't work properly on large title. To solve the issue set top constraint | |
of tableView to the super view */ | |
lazy var refresher: UIRefreshControl = { | |
let refreshControl = UIRefreshControl() | |
refreshControl.tintColor = UIColor(hexString: colorPrimary) | |
refreshControl.addTarget(self, action: #selector(refreshContents), for: .valueChanged) | |
return refreshControl | |
}() | |
init(tableView: UITableView, | |
cellIdentifer: String, | |
sDelegate: SSAdapterDelegate) { | |
self.tv = tableView | |
self.cellIdentifier = cellIdentifer | |
self.sDelegate = sDelegate | |
super.init() | |
self.addRefreshControl() | |
} | |
func addRefreshControl(){ | |
if #available(iOS 10.0, *){ | |
self.tv.refreshControl = refresher | |
}else{ | |
self.tv.addSubview(refresher) | |
} | |
} | |
@objc func refreshContents(){ | |
sDelegate?.refreshTableData() | |
} | |
func isRefreshing()-> (Bool){ | |
return refresher.isRefreshing | |
} | |
func addLoadingFooter(){ | |
let spinner = UIActivityIndicatorView(style: .gray) | |
spinner.startAnimating() | |
spinner.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tv.bounds.width, height: CGFloat(44)) | |
tv.tableFooterView = spinner | |
tv.tableFooterView?.isHidden = false | |
} | |
func removeLoadingFooter(){ | |
tv.tableFooterView = nil | |
} | |
func addAll(itemList:[T]){ | |
tableData += itemList | |
notifyDataSetChanged() | |
} | |
func addItem(item: T){ | |
tableData.append(item) | |
let lastRow: Int = tv.numberOfRows(inSection: 0) | |
let indexPath = IndexPath(row: lastRow, section: 0); | |
tv.insertRows(at: [indexPath], with: .automatic) | |
} | |
func removeItem(position: Int){ | |
tableData.remove(at: position) | |
let indexPath = IndexPath(row: position, section: 0); | |
tv.deleteRows(at: [indexPath], with: .automatic) | |
} | |
func notifyDataSetChanged(){ | |
if refresher.isRefreshing{ | |
refresher.endRefreshing() | |
} | |
tv.reloadData() | |
} | |
//////////////////////////////////////////////////////////////////////////// | |
func numberOfSections(in tableView: UITableView) -> Int { | |
return 1 | |
} | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return tableData.count | |
} | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) else { return UITableViewCell() } | |
return cell | |
} | |
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { | |
sDelegate?.willDisplay(cell: cell, indexPath: indexPath) | |
if (indexPath.row == tableData.count - 1 ){ | |
if (sDelegate?.hasNextPage() ?? false) && !(sDelegate?.isLoadingFooterAdded() ?? false) { | |
addLoadingFooter() | |
sDelegate?.loadMoreData() | |
} | |
} | |
} | |
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | |
sDelegate?.didSelected(indexPath: indexPath) | |
} | |
} | |
extension UITableView { | |
func setAdapter<T>(_ adapter: SSAdapter<T>) { | |
dataSource = adapter | |
delegate = adapter | |
tableFooterView = UIView(frame: CGRect.zero) | |
reloadData() | |
} | |
} | |
/////////////////////////////////////////// HOW TO USE//////////////////////////////////////////////// | |
class LockRequestViewController: BaseViewController { | |
var presenter: LockRequestPresenterProtocol? | |
@IBOutlet weak var tableView: UITableView! | |
var lockRequests:[SingleLockRequest] = [SingleLockRequest]() | |
var nextPageUrl: String? | |
var isLoadingAdded: Bool = false | |
var adapter: SSAdapter<SingleLockRequest>! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
setupAddBarBtn() // Add a addLockRequest Bar button to the navigation Bar......... | |
adapter = SSAdapter(tableView: tableView, cellIdentifer: LockRequestTableViewCell.className, sDelegate: self) | |
tableView.rowHeight = 70 | |
tableView.setAdapter(adapter) | |
LockRequestAllWireFrame.createLockRequestsModule(view: self) | |
presenter?.getLockRequestAll(url: APIs.GET_LOCK_REQUEST_ALL) | |
} | |
func setupAddBarBtn(){ | |
let addBtn = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addBtnDidTapped)) | |
self.navigationItem.rightBarButtonItem = addBtn | |
} | |
@objc func addBtnDidTapped(){ | |
performSegue(withIdentifier: "add_lock_request", sender: nil) | |
} | |
override func networkCallDidStarted(_ loadingMsg: String) { | |
if !(isLoadingAdded || adapter.isRefreshing()){ | |
SVProgressHUD.show(withStatus: loadingMsg) | |
} | |
} | |
} | |
extension LockRequestViewController: LockRequestViewProtocol{ | |
func lockRequestDidReceived(lock: Locks) { | |
if(adapter.isRefreshing()){ | |
self.lockRequests.removeAll() | |
adapter.tableData.removeAll() | |
} | |
nextPageUrl = lock.nextPageURL | |
lockRequests += lock.data | |
adapter.addAll(itemList: lock.data) | |
if(isLoadingAdded){ | |
isLoadingAdded = false | |
adapter.removeLoadingFooter() | |
} | |
} | |
} | |
extension LockRequestViewController: SSAdapterDelegate { | |
func isLoadingFooterAdded() -> Bool { | |
return isLoadingAdded | |
} | |
func loadMoreData() { | |
isLoadingAdded = true | |
presenter?.getLockRequestAll(url: nextPageUrl!) | |
} | |
func refreshTableData() { | |
presenter?.getLockRequestAll(url: APIs.GET_LOCK_REQUEST_ALL) | |
} | |
func hasNextPage() -> Bool { | |
return nextPageUrl != nil | |
} | |
func willDisplay(cell: UITableViewCell, indexPath: IndexPath) { | |
if (cell is LockRequestTableViewCell){ | |
let lockCell: LockRequestTableViewCell = cell as! LockRequestTableViewCell | |
lockCell.configData(singleLockData: lockRequests[indexPath.row]) | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment