使用 Swift 创建分页 UICollectionView
Posted
技术标签:
【中文标题】使用 Swift 创建分页 UICollectionView【英文标题】:Create a Paging UICollectionView with Swift 【发布时间】:2015-07-11 08:42:48 【问题描述】:我正在尝试创建一个带有分页的 UICollectionView,并且每个项目的最大宽度为 250 点,我已经设法创建它,但我有两个问题:第一个项目不是应该的那样开始,而是更多开始时有空格,当我尝试滑动时,总会有一些东西让我无法流畅地滑动。
看起来是这样的:
video link
这是我的代码:
CenterCellCollectionFlowLayout.swift
class CenterCellCollectionViewFlowLayout: UICollectionViewFlowLayout
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]?
var attributesToReturn:[UICollectionViewLayoutAttributes] = super.layoutAttributesForElementsInRect(rect) as! [UICollectionViewLayoutAttributes]
for var i = 0 ; i < attributesToReturn.count ; i++
var currentLayoutAttributes: UICollectionViewLayoutAttributes = attributesToReturn[i]
var maximumSpacing: CGFloat = 50
let origin: CGFloat
if i - 1 >= 0
let previousLayoutAttributes = attributesToReturn[i - 1]
origin = previousLayoutAttributes.frame.maxX
else
origin = 0
if origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize().width
var frame: CGRect = currentLayoutAttributes.frame
frame.origin.x = origin + maximumSpacing
currentLayoutAttributes.frame = frame
return attributesToReturn
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint
if let cv = self.collectionView
let cvBounds = cv.bounds
let halfWidth = cvBounds.size.width * 0.5;
let proposedContentOffsetCenterX = proposedContentOffset.x + halfWidth;
if let attributesForVisibleCells = self.layoutAttributesForElementsInRect(cvBounds) as? [UICollectionViewLayoutAttributes]
var candidateAttributes : UICollectionViewLayoutAttributes?
for attributes in attributesForVisibleCells
// == Skip comparison with non-cell items (headers and footers) == //
if attributes.representedElementCategory != UICollectionElementCategory.Cell
continue
if let candAttrs = candidateAttributes
let a = attributes.center.x - proposedContentOffsetCenterX
let b = candAttrs.center.x - proposedContentOffsetCenterX
if fabsf(Float(a)) < fabsf(Float(b))
candidateAttributes = attributes;
else // == First time in the loop == //
candidateAttributes = attributes;
continue;
return CGPoint(x : candidateAttributes!.center.x - halfWidth, y : proposedContentOffset.y);
// Fallback
return super.targetContentOffsetForProposedContentOffset(proposedContentOffset)
MainViewController.swift
class MainViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var collectionViewFlowLayout: CenterCellCollectionViewFlowLayout!
var collectionObjects: NSMutableArray?
private let reuseIdentifier = "CollectionViewCell"
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
self.collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UICollectionViewCell
cell.backgroundColor = UIColor.greenColor()
// Configure the cell
return cell
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 10
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets
return UIEdgeInsetsMake(0, 0, 0, 0)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
return CGSizeMake(250, 250)
提前致谢
【问题讨论】:
【参考方案1】:UICollectionView 继承自 UIScrollView。可以通过设置isPagingEnabled为true来实现分页。
【讨论】:
您刚刚使所有其他答案无效!为我工作,谢谢 天哪,伙计,我以为我需要重做所有收藏视图的工作,但你救了我的命!【参考方案2】:所以我想出了怎么做。
首先创建一个自定义的 UICollectionViewFlowLayout 并添加这个覆盖这个方法:
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint
if let cv = self.collectionView
let cvBounds = cv.bounds
let halfWidth = cvBounds.size.width * 0.5;
let proposedContentOffsetCenterX = proposedContentOffset.x + halfWidth;
if let attributesForVisibleCells = self.layoutAttributesForElementsInRect(cvBounds) as? [UICollectionViewLayoutAttributes]
var candidateAttributes : UICollectionViewLayoutAttributes?
for attributes in attributesForVisibleCells
// == Skip comparison with non-cell items (headers and footers) == //
if attributes.representedElementCategory != UICollectionElementCategory.Cell
continue
if let candAttrs = candidateAttributes
let a = attributes.center.x - proposedContentOffsetCenterX
let b = candAttrs.center.x - proposedContentOffsetCenterX
if fabsf(Float(a)) < fabsf(Float(b))
candidateAttributes = attributes;
else // == First time in the loop == //
candidateAttributes = attributes;
continue;
return CGPoint(x : candidateAttributes!.center.x - halfWidth, y : proposedContentOffset.y);
// Fallback
return super.targetContentOffsetForProposedContentOffset(proposedContentOffset)
然后在你实现 UICollectionView 的类上这样做:
let collectionViewLayout: CenterCellCollectionViewFlowLayout = CenterCellCollectionViewFlowLayout()
collectionViewLayout.itemSize = CGSizeMake(self.itemSize, self.itemSize)
collectionViewLayout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
collectionViewLayout.minimumInteritemSpacing = 0
collectionViewLayout.minimumLineSpacing = self.itemSpacing
collectionViewLayout.scrollDirection = UICollectionViewScrollDirection.Horizontal
var collectionView: UICollectionView = UICollectionView(frame: self.collectionContainer.bounds, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.backgroundColor = UIColor.redColor()
collectionView.registerClass(LevelsCustomCell.self, forCellWithReuseIdentifier: reuseIdentifier)
collectionView.registerNib(UINib(nibName: reuseIdentifier, bundle: nil), forCellWithReuseIdentifier: reuseIdentifier)
self.collectionContainer.addSubview(collectionView)
就是这样,就像一个魅力。
【讨论】:
当你复制粘贴别人的代码时,你至少可以参考它:randexdev.com/2014/07/uicollectionview 这个代码对我来说比 karmadust 更好 工作就像一个魅力! 我想给予信任,但两个网站都无法正常工作。无论如何,我只是想帮助人们,而不是窃取某人的代码。 谢谢!对于我的用例,布局代码使单元格“对齐”到中心,这很棒。以上是关于使用 Swift 创建分页 UICollectionView的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中使用分页向 UIScrollview 添加子视图
如何使用 MovieDB API Swift 为 TableView 进行分页?
使用 Swift 进行 Firebase Firestore 分页
使用 Firebase Firestore 进行分页 - swift 4