How do I create a horizontal scrolling UICollectionView in Swift?

前端 未结 3 647
灰色年华
灰色年华 2020-12-13 07:37

How can I 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

3条回答
  •  有刺的猬
    2020-12-13 08:28

    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
    }
    

提交回复
热议问题