Создание горизонтальной прокрутки collectionview в Swift

Как я могу легко сделать горизонтальную прокрутку collectionView, которая заполняет ячейки, идущие через строки, а не вниз по столбцам?

Я хочу, чтобы было 5 столбцов и 3 строки, но когда есть более 15 элементов, я хочу, чтобы он прокрутился на следующую страницу.
У меня много проблем с этим.

2 ответов


Вариант 1 - Рекомендуется

использовать пользовательские макеты для представления коллекции. Это правильный способ сделать это, и это дает вам большой контроль над тем, как вы хотите, чтобы ваши ячейки заполняли представление коллекции.

здесь UICollectionView Пользовательский Макет Учебник из "raywenderlich"


2

это больше похоже на хакерский способ делать то, что вы хотите. В этом методе вы можете получить доступ к источнику данных в целях сымитировать стиль, который вам нужен. Я объясню это в коде:

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
}

вот этот код в действии:

enter image description here

*кнопка "Добавить" просто добавляет еще один номер в myArray и перезагружает представление коллекции, чтобы продемонстрировать, как это будет выглядеть с различным количеством элементов в myArray


редактировать - группировать элементы на страницы:

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
}

где у вас есть ссылка на ваш UICollectionViewFlowLayout(), просто сделать:

layout.scrollDirection = .horizontal

вот хороший учебник для получения дополнительной информации:https://www.youtube.com/watch?v=Ko9oNhlTwH0

хотя для исторических целей рассмотрите возможность быстрого поиска StackOverFlow, чтобы убедиться, что это не дубликат.

надеюсь, что это помогает.

обновление: Сначала ваши элементы будут заполняться горизонтально, и если в collectionview недостаточно места справа они пойдут в следующий ряд. Итак, начните с увеличения вашего collectionview.contentsize (должно быть больше экрана, чтобы включить прокрутку), а затем установите размер элемента collectionview (ячейки).

flowLayout.itemSize = CGSize(width: collectionView.contentSize.width/5, height: collectionView.contentSize.height/3)