如何在 UICollectionView 中快速添加分页?
Posted
技术标签:
【中文标题】如何在 UICollectionView 中快速添加分页?【英文标题】:How to add pagination in UICollectionView in swift? 【发布时间】:2018-07-11 09:41:58 【问题描述】:我有一个显示项目的 UICollection 视图。现在我想在 UICollectionView 上添加分页。我不想为此功能使用任何第三方。请告诉我如何实现这一目标!
我有四个一例http://slicode.com/bottom-refresh-control-uicollectionview/
但在此我必须向上拖动滚动视图几秒钟才能使其工作。
【问题讨论】:
检查collectionView contentOffset,如果滚动到达底部则调用下一页。您也可以以编程方式开始刷新 refreshControl。 你能提供一些代码吗? 你的问题解决了吗? 是的,我接受了你的回答。学习这些课程超级简单 【参考方案1】:简单的方法
var page: Int = 0
var isPageRefreshing:Bool = false
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
YourApi(page1: 0)
func scrollViewDidScroll(_ scrollView: UIScrollView)
if(self.mycollectionview.contentOffset.y >= (self.mycollectionview.contentSize.height - self.mycollectionview.bounds.size.height))
if !isPageRefreshing
isPageRefreshing = true
print(page)
page = page + 1
YourApi(page1: page)
在您的 api 方法中
func YourApi(page1: Int)
let mypage = String(page1)
let request: String = String.init(format:"apiName/%@", mypage)
print(request)
就是这样。
【讨论】:
【参考方案2】:如果你想添加底部刷新控件,你必须使用下面的帮助类。
https://github.com/vlasov/CCBottomRefreshControl/tree/master/Classes
下载这两个在 Objective-C 中的文件。您必须在桥接头中导入此文件
#import "UIScrollView+BottomRefreshControl.h"
像这样添加刷新控件。
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
这个帮助类为您提供了新的bottomRefreshControl
属性,它可以帮助您在底部添加刷新控件。
【讨论】:
这里 fetchNextData() 与刷新的关系。应该调用哪个方法 @Techiee 将#selector(refresh)
替换为 #selector(fetchNextData)
可能对您有用。
我在集合视图中添加了刷新控件作为子视图,但它没有显示在页脚中。它显示为集合视图顶部作为拉刷新
@Techiee 你是只滚动垂直/水平方向还是双向滚动
仅垂直方向【参考方案3】:
我已经在我的一个应用程序中添加了加载更多功能,所以让我给你代码
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 view = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "footer", for: indexPath)
let loading = UIActivityIndicatorView()
loading.activityIndicatorViewStyle = .gray
loading.translatesAutoresizingMaskIntoConstraints = false
loading.tintColor = UIColor.gray
loading.tag = -123456
view.addSubview(loading)
view.addConstraint(NSLayoutConstraint(item: loading, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0))
vew.addConstraint(NSLayoutConstraint(item: loading, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0))
return view
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
【讨论】:
如何维护 isLastPageReached ?这个函数用在哪里 self.removeLoadMoreView ? @Techiee 你需要在 api 响应中管理的布尔值。如果两者相同,我得到页面总数和当前页面,那么 bool 将变为 true,否则为 false 这个函数在哪里使用 self.removeLoadMoreView ? - 让我编辑我的答案 请问您定义了哪些常量?例如isLoadMore
【参考方案4】:
请试试这个对我有用。
第 1 步:
声明一个全局变量:
var totalCount : NSInteger?
var isGetResponse : Bool = true
var activityIndiator : UIActivityIndicatorView?
设置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!)
第 2 步: 在api调用方法中设置值:
self.totalCount = array.count
self.isGetResponse = true
第 3 步: 写下这段代码:
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
在服务调用中,您可以发送页面索引,然后从服务器端返回响应。
谢谢。
【讨论】:
你在哪里定义totalArrayCount
和 pageIndex
这个解决方案看起来不错,但很混乱
谢谢,对我来说最好使用scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height
【参考方案5】:
CollectionView 委托方法:在 CollectionView 上加载更多关于 Scroll Demand 的数据。
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.
【讨论】:
【参考方案6】:以下两个函数负责分页。如下所示。
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
if current_page < total_page && indexPath.row == cars.count - 1
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "loading_cell", for: indexPath) as! PaginationCollectionViewCell
cell.actIndicator.startAnimating()
return cell
else
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! PaginationCollectionViewCell
cell.lbTitle.text = cars[indexPath.row].company_name
cell.lbDescription.text = cars[indexPath.row].engine_power
return cell
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
if current_page < total_page && indexPath.row == cars.count - 1
current_page = current_page + 1
DispatchQueue.main.asyncAfter(deadline: .now() + 10)
self.fetchData(page: self.current_page)
【讨论】:
【参考方案7】:我在进行分页时使用了该代码。 重点是;在集合视图加载时捕获加载的单元格索引,并使用数字控制它的 mod,并使用 api 中的页面大小字段单独获取数据(如果有)。您可以决定哪个数字将小于此计算,并且您将控制它。
例如,您获取了 5 个数据并加载了它,如果此状态正常,您将获取其他 5 个。这是示例代码。
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()
在这段代码中,我控制 indexpath.row % 3 == 1 与否。它可能有点复杂,所以如果你愿意,我可以分享一个代码块。祝你好运:)
【讨论】:
【参考方案8】:-- itemList - 你的数据数组。
-- pageCount - 用于跟踪页数的变量。
-- totalCount - 数据总数
--- 每次调用 API 时将数据附加到 itemList。
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
if indexPath.row == itemList.count - 1 && itemList.count < totalCount
pageCount += 1
// Call API here
【讨论】:
【参考方案9】:willDisplay cell
方法中的代码调用 load more 函数,而您的滚动条距离末端 5 个单元格。获取数据时在集合视图页脚中显示加载程序。加载完成后隐藏页脚。
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
【讨论】:
以上是关于如何在 UICollectionView 中快速添加分页?的主要内容,如果未能解决你的问题,请参考以下文章
如何快速从 UICollectionView 中的 UIView 中删除焦点阴影?
如何快速获取两个 UICollectionView 的 ScrollView?
如何在我的 iOS 应用程序中添加一项权利,以便在请求 Apple 之前快速测试它是不是有效