ios 如何在 Swift 中创建水平滚动 UICollectionView?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39946022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a horizontal scrolling UICollectionView in Swift?
提问by user6520705
How can I make a horizontal scrolling collectionView that fills up cells going across the rows rather than down the columns?
如何制作一个水平滚动的 collectionView 来填充跨越行而不是向下列的单元格?
I want there to 5 columns and 3 rows but when there is more than 15 items I want it to scroll to the next page. I'm having a lot of trouble getting this going.
我想要 5 列和 3 行,但是当项目超过 15 个时,我希望它滚动到下一页。我很难做到这一点。
采纳答案by Sam_M
Option 1 - Recommended
选项 1 - 推荐
Use custom layouts for your collection view. This is the right way to do this and it gives you a lot of control over how you want your cells to fill the collection view.
为您的集合视图使用自定义布局。这是执行此操作的正确方法,它使您可以对希望单元格如何填充集合视图进行大量控制。
Here is a UICollectionView Custom Layout Tutorialfrom "raywenderlich"
这是来自“raywenderlich”的UICollectionView 自定义布局教程
Option 2
选项 2
This is more like a hackish way of doing what you want. In this method you can access your data source in an order to simulate the style you need. I'll explain it in the code:
这更像是一种做你想做的事情的黑客方式。在此方法中,您可以按顺序访问数据源以模拟所需的样式。我会在代码中解释一下:
var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
let rows = 3
let columnsInFirstPage = 5
// calculate number of columns needed to display all items
var columns: Int { return myArray.count<=columnsInFirstPage ? myArray.count : myArray.count > rows*columnsInFirstPage ? (myArray.count-1)/rows + 1 : columnsInFirstPage }
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return columns*rows
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
//These three lines will convert the index to a new index that will simulate the collection view as if it was being filled horizontally
let i = indexPath.item / rows
let j = indexPath.item % rows
let item = j*columns+i
guard item < myArray.count else {
//If item is not in myArray range then return an empty hidden cell in order to continue the layout
cell.hidden = true
return cell
}
cell.hidden = false
//Rest of your cell setup, Now to access your data You need to use the new "item" instead of "indexPath.item"
//like: cell.myLabel.text = "\(myArray[item])"
return cell
}
Here is this code in action:
这是运行中的代码:
*The "Add" button just adds another number to myArray
and reloads the collection view to demonstrate how it would look with different number of items in myArray
*“添加”按钮只是myArray
向集合视图添加另一个数字并重新加载集合视图以演示它在不同数量的项目中的外观myArray
Edit- Group items into pages:
编辑- 将项目分组为页面:
var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
let rows = 3
let columnsInPage = 5
var itemsInPage: Int { return columnsInPage*rows }
var columns: Int { return myArray.count%itemsInPage <= columnsInPage ? ((myArray.count/itemsInPage)*columnsInPage) + (myArray.count%itemsInPage) : ((myArray.count/itemsInPage)+1)*columnsInPage }
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return columns*rows
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
let t = indexPath.item / itemsInPage
let i = indexPath.item / rows - t*columnsInPage
let j = indexPath.item % rows
let item = (j*columnsInPage+i) + t*itemsInPage
guard item < myArray.count else {
cell.hidden = true
return cell
}
cell.hidden = false
return cell
}
回答by Ian Moses
Where you have a reference to your UICollectionViewFlowLayout()
, just do:
如果您有对您的引用,请UICollectionViewFlowLayout()
执行以下操作:
layout.scrollDirection = .horizontal
Here is a nice tutorial for more info: https://www.youtube.com/watch?v=Ko9oNhlTwH0
这是一个很好的教程以获取更多信息:https: //www.youtube.com/watch?v=Ko9oNhlTwH0
Though for historical purposes, consider searching StackOverFlow quickly to make sure this isn't a duplicate.
尽管出于历史目的,请考虑快速搜索 StackOverFlow 以确保这不是重复的。
Hope this helps.
希望这可以帮助。
Update:Your items will fill horizontally first and if there is not enough room within the collectionview going to the right, they will go to next row. So, start by increasing your collectionview.contentsize
(should be larger the screen to enable scrolling) and then set your collectionview item (cell) size.
更新:您的项目将首先水平填充,如果右侧的 collectionview 中没有足够的空间,它们将转到下一行。因此,首先增加您的collectionview.contentsize
(应该更大的屏幕以启用滚动),然后设置您的 collectionview 项目(单元格)大小。
flowLayout.itemSize = CGSize(width: collectionView.contentSize.width/5, height: collectionView.contentSize.height/3)
回答by craft
Specify the height of the collection view and cell size. More details below:
指定集合视图的高度和单元格大小。更多详情如下:
Set the constraints of the UICollectionView, pinning the edges. Be sure to specify the UICollectionView's height or constraints so it's clear the cells can only scroll horizontally and not go down to the next line. The height should be the same or slightly larger than the cell height you specify in step 2.
Implement the
UICollectionViewDelegateFlowLayout
delegate andsizeForItemAt
method. Here's a sample sizeForItemAt implementation.func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let cellWidth = 100 let cellHeight = 30 return CGSize(width: cellWidth, height: cellHeight) }
设置 UICollectionView 的约束,固定边缘。请务必指定 UICollectionView 的高度或约束,以便很明显单元格只能水平滚动而不能向下滚动到下一行。高度应与您在步骤 2 中指定的单元格高度相同或略大。
实现
UICollectionViewDelegateFlowLayout
委托和sizeForItemAt
方法。这是一个示例 sizeForItemAt 实现。func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let cellWidth = 100 let cellHeight = 30 return CGSize(width: cellWidth, height: cellHeight) }