Abd*_*man 33 uiscrollview uiscrollviewdelegate ios uicollectionview swift
我想实现UICollectionView
水平和无限滚动?
cic*_*rgo 39
如果您的数据是静态的并且您想要一种循环行为,则可以执行以下操作:
var dataSource = ["item 0", "item 1", "item 2"]
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Int.max // instead of returnin dataSource.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let itemToShow = dataSource[indexPath.row % dataSource.count]
let cell = UICollectionViewCell() // setup cell with your item and return
return cell
}
Run Code Online (Sandbox Code Playgroud)
基本上你对你的集合视图说你有大量的单元格(Int.max不会是无限的,但可能会这样做),并且你使用%运算符访问你的数据源.在我的例子中,我们最终得到"项目0","项目1","项目2","项目0","项目1","项目2"....
我希望这有帮助 :)
Bio*_*tic 10
显然,最接近良好解决方案的是Manikanta Adimulam提出的.最干净的解决方案是在数据列表的开头添加最后一个元素,并将第一个元素添加到最后一个数据列表位置(例如:[4] [0] [1] [2] [3] [4] [ 0]),所以我们在触发最后一个列表项时滚动到第一个数组项,反之亦然.这适用于具有一个可见项的集合视图:
覆盖UICollectionViewDelegate并覆盖以下方法:
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let numberOfCells = items.count
let page = Int(scrollView.contentOffset.x) / Int(cellWidth)
if page == 0 { // we are within the fake last, so delegate real last
currentPage = numberOfCells - 1
} else if page == numberOfCells - 1 { // we are within the fake first, so delegate the real first
currentPage = 0
} else { // real page is always fake minus one
currentPage = page - 1
}
// if you need to know changed position, you can delegate it
customDelegate?.pageChanged(currentPage)
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
let numberOfCells = items.count
if numberOfCells == 1 {
return
}
let regularContentOffset = cellWidth * CGFloat(numberOfCells - 2)
if (scrollView.contentOffset.x >= cellWidth * CGFloat(numberOfCells - 1)) {
scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x - regularContentOffset, y: 0.0)
} else if (scrollView.contentOffset.x < cellWidth) {
scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x + regularContentOffset, y: 0.0)
}
}
Run Code Online (Sandbox Code Playgroud)覆盖UICollectionView中的layoutSubviews()方法,以便始终为第一个项目创建正确的偏移量:
override func layoutSubviews() {
super.layoutSubviews()
let numberOfCells = items.count
if numberOfCells > 1 {
if contentOffset.x == 0.0 {
contentOffset = CGPoint(x: cellWidth, y: 0.0)
}
}
}
Run Code Online (Sandbox Code Playgroud)覆盖init方法并计算单元格尺寸:
let layout = self.collectionViewLayout as! UICollectionViewFlowLayout
cellPadding = layout.minimumInteritemSpacing
cellWidth = layout.itemSize.width
Run Code Online (Sandbox Code Playgroud)奇迹般有效!如果要在具有多个可见项的集合视图中实现此效果,请使用此处发布的解决方案.
我已经在 中实现了无限滚动UICollectionView
。使代码在 github 中可用。你可以尝试一下。它在 swift 3.0 中。
您可以使用 pod 添加它。使用方法非常简单。只需初始化InfiniteScrollingBehaviour
如下即可。
infiniteScrollingBehaviour = InfiniteScrollingBehaviour(withCollectionView: collectionView, andData: Card.dummyCards, delegate: self)
Run Code Online (Sandbox Code Playgroud)
并实现所需的委托方法以返回配置的UICollectionViewCell
. 示例实现如下所示:
func configuredCell(forItemAtIndexPath indexPath: IndexPath, originalIndex: Int, andData data: InfiniteScollingData, forInfiniteScrollingBehaviour behaviour: InfiniteScrollingBehaviour) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellID", for: indexPath)
if let collectionCell = cell as? CollectionViewCell,
let card = data as? Card {
collectionCell.titleLabel.text = card.name
}
return cell
}
Run Code Online (Sandbox Code Playgroud)
它将在原始数据集中添加适当的前导和尾随边界元素,并调整 collectionView 的contentOffset
.
在回调方法中,它将为您提供原始数据集中某个项目的索引。
测试代码
我通过简单地重复单元 x 次来实现这一点。如下,
声明您想要有多少个循环
let x = 50
Run Code Online (Sandbox Code Playgroud)
实施numberOfItems
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return myArray.count*x // large scrolling: lets see who can reach the end :p
}
Run Code Online (Sandbox Code Playgroud)
添加此实用程序函数来计算arrayIndex
给定的 indexPath 行
func arrayIndexForRow(_ row : Int)-> Int {
return row % myArray.count
}
Run Code Online (Sandbox Code Playgroud)
实施cellForItem
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myIdentifier", for: indexPath) as! MyCustomCell
let arrayIndex = arrayIndexForRow(indexPath.row)
let modelObject = myArray[arrayIndex]
// configure cell
return cell
}
Run Code Online (Sandbox Code Playgroud)
collectionView
添加实用程序函数以滚动到给定索引的中间
func scrollToMiddle(atIndex: Int, animated: Bool = true) {
let middleIndex = atIndex + x*yourArray.count/2
collectionView.scrollToItem(at: IndexPath(item: middleIndex, section: 0), at: .centeredHorizontally, animated: animated)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
31048 次 |
最近记录: |