且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在Swift中创建水平滚动集合视图

更新时间:2023-11-17 16:09:28

选项1 - 推荐



为集合视图使用自定义布局。这是执行此操作的正确方法,它可以让您对单元格如何填充集合视图进行大量控制。



这是



*添加按钮只是将另一个数字添加到 myArray 并重新加载集合视图以演示它与不同的外观 myArray中的项目数






编辑 - 将项目分组到页面中:

  var m yArray = [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
}


How can I easily make a horizontal scrolling collectionView that fills up Cells going across the rows rather than down the columns?

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 alot of trouble getting this going.

Option 1 - Recommended

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 Tutorial from "raywenderlich"


Option 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


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
}