I have a UICollection view which shows items. Now I want to add pagination on UICollectionView. I do not want to use any third party for this functionality. Please let me know how I can achieve this!
I have four one example http://slicode.com/bottom-refresh-control-uicollectionview/
But in this I have to drag scrollview upwards for few second to make it work.
7 Answers
Answers 1
I have added the functionality of load more in one of my application so let me give you the code
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { if arrData.count > 0 && isLastPageReached == false { return CGSize(width:(collectionView.frame.size.width), height: 100.0) } return CGSize.zero } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { if kind == UICollectionElementKindSectionFooter { let vew = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "footer", for: indexPath) let loading = UIActivityIndicatorView() loading.activityIndicatorViewStyle = .gray loading.translatesAutoresizingMaskIntoConstraints = false loading.tintColor = UIColor.gray loading.tag = -123456 vew.addSubview(loading) vew.addConstraint(NSLayoutConstraint(item: loading, attribute: .centerX, relatedBy: .equal, toItem: vew, attribute: .centerX, multiplier: 1, constant: 0)) vew.addConstraint(NSLayoutConstraint(item: loading, attribute: .centerY, relatedBy: .equal, toItem: vew, attribute: .centerY, multiplier: 1, constant: 0)) return vew } return UICollectionReusableView() } func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath) { if elementKind == UICollectionElementKindSectionFooter { if let loadingView = view.viewWithTag(-123456) as? UIActivityIndicatorView{ if arrData.count > 0 && isLastPageReached == false { loadingView.startAnimating() self.loadMore() } else { self.isLoadMore = false } } } } func collectionView(_ collectionView: UICollectionView, didEndDisplayingSupplementaryView view: UICollectionReusableView, forElementOfKind elementKind: String, at indexPath: IndexPath) { if elementKind == UICollectionElementKindSectionFooter{ if let loadingView = view.viewWithTag(-123456) as? UIActivityIndicatorView{ loadingView.stopAnimating() loadingView.removeFromSuperview() self.isLoadMore = false } } }
Answers 2
If you want to add bottom refresh control you have to use below helper class.
https://github.com/vlasov/CCBottomRefreshControl/tree/master/Classes
Download this 2 files which is in Objective-C. You have to import this file in Bridging header
#import "UIScrollView+BottomRefreshControl.h"
Add refresh control like this.
let refreshControl = UIRefreshControl.init(frame: CGRect(x: 0, y: 0, width: 50, height: 50)) refreshControl.triggerVerticalOffset = 50.0 refreshControl.addTarget(self, action: #selector(paginateMore), for: .valueChanged) collectionView.bottomRefreshControl = refreshControl
This helper class provide you new bottomRefreshControl
property, which helps you to add refresh control in bottom.
Answers 3
Please try this it works for me.
Step 1:
Declare a global variable :
var totalCount : NSInteger? var isGetResponse : Bool = true var activityIndiator : UIActivityIndicatorView?
Set the viewDidLoad:
activityIndiator = UIActivityIndicatorView(frame: CGRect(x: self.view.frame.midX - 15, y: self.view.frame.height - 140, width: 30, height: 30)) activityIndiator?.activityIndicatorViewStyle = .white activityIndiator?.color = UIColor.black activityIndiator?.hidesWhenStopped = true activityIndiator?.backgroundColor = COLOR.COLOR_TABLEVIEW_BACKGROUND activityIndiator?.layer.cornerRadius = 15 self.view.addSubview(activityIndiator!) self.view.bringSubview(toFront: activityIndiator!)
Step 2: Set the value in the api call method:
self.totalCount = array.count self.isGetResponse = true
Step 3: Write this code :
func scrollViewDidScroll(_ scrollView: UIScrollView) { if isGetResponse { if (scrollView.contentOffset.y == scrollView.contentSize.height - scrollView.frame.size.height) { if totalArrayCount! > self.arrProductListing.count{ isGetResponse = false activityIndiator?.startAnimating() self.view.bringSubview(toFront: activityIndiator!) pageIndex = pageIndex + 1 print(pageIndex) self.getProductListing(withPageCount: pageIndex) } } //LOAD MORE // you can also add a isLoading bool value for better dealing :D } }
In service call you can send the page index and from the server end they send back the response.
Thank you.
Answers 4
The code in willDisplay cell
method calls load more function while your scroll is 5 cells away from the end. While fetching data show loader in collection view footer. Hide footer when loading is completed.
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { let currentPage = collectionView.contentOffset.y / collectionView.frame.size.width; if (aryDataSource.count >= yourAPIResponsebatchCount && aryDataSource.count - indexPath.row == 5 && currentPage >= currentPage && isDataLoading) { currentPage++; self.fetchMoreData() } else { } }
Answers 5
I used that code while doing pagination. The point is; catching the loaded cell index while collection view is loading and control it's mod with a number and fetch datas seperately with page size field in the api (if there is). You can decide which number will be smaller than this calculation and you will control it.
For example you fetched 5 datas and loaded it and, if this state is ok, you will fetch the other 5. Here is the sample code for that.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if let vc = self.parentViewController as? SellController { if vc.dontFetch == false { DispatchQueue.main.async { if self.salesData.count > 3 { if indexPath.row != 1 { if indexPath.row % 3 == 1 { print("indexpath: \(indexPath.row)") vc.pagination += 1 vc.reload() } } } } } } }
In this code i am controlling indexpath.row % 3 == 1 or not. It can be little bit complex so i can share a code block if you want. Good luck:)
Answers 6
CollectionView Delegate method: Load More data on Scroll Demand on CollectionView.
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { if indexPath.row == numberofitem.count - 1 { //numberofitem count updateNextSet() } } func updateNextSet(){ print("On Completetion") //requests another set of data (20 more items) from the server. }
Answers 7
-- itemList - your data array.
-- pageCount - variable used to keep track of the number of pages.
-- totalCount - total number of data
--- append data to itemList every time you call the API.
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { if indexPath.row == itemList.count - 1 && itemList.count < totalCount{ pageCount += 1 // Call API here } }
0 comments:
Post a Comment