web-dev-qa-db-fra.com

Comment créer un UICollectionView à défilement horizontal dans Swift?

Comment puis-je créer une collectionView à défilement horizontal qui remplit les cellules qui traversent les lignes plutôt que les colonnes?

Je veux qu'il y ait 5 colonnes et 3 lignes, mais lorsqu'il y a plus de 15 éléments, je veux qu'il défile à la page suivante. J'ai beaucoup de mal à démarrer.

11
user6520705

Option 1 - Recommandé

Utilisez des dispositions personnalisées pour la vue de votre collection. C'est la bonne façon de procéder et cela vous donne beaucoup de contrôle sur la façon dont vous souhaitez que vos cellules remplissent la vue de la collection.

Voici un Tutoriel de mise en page personnalisée UICollectionView de "raywenderlich"


Option 2

Cela ressemble plus à une façon hackeuse de faire ce que vous voulez. Dans cette méthode, vous pouvez accéder à votre source de données afin de simuler le style dont vous avez besoin. Je vais l'expliquer dans le 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
}

Voici ce code en action:

enter image description here

* Le bouton "Ajouter" ajoute simplement un autre numéro à myArray et recharge la vue de collection pour montrer à quoi cela ressemblerait avec un nombre différent d'éléments dans myArray


Modifier - Grouper les éléments en 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
}
9
Sam_M

Lorsque vous avez une référence à votre UICollectionViewFlowLayout(), faites simplement:

layout.scrollDirection = .horizontal

Voici un joli tutoriel pour plus d'informations: https://www.youtube.com/watch?v=Ko9oNhlTwH

Bien qu'à des fins historiques, envisagez de rechercher StackOverFlow rapidement pour vous assurer qu'il ne s'agit pas d'un doublon.

J'espère que cela t'aides.

Mise à jour: Vos articles se rempliront d'abord horizontalement et s'il n'y a pas assez de place dans la vue de collection à droite, ils iront à la ligne suivante. Alors, commencez par augmenter votre collectionview.contentsize (devrait être plus grand à l'écran pour permettre le défilement), puis définissez la taille de votre élément de collectionview (cellule).

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

Spécifiez la hauteur de la vue de collection et la taille de cellule. Plus de détails ci-dessous:

  1. Définissez les contraintes de l'UICollectionView en épinglant les bords. Assurez-vous de spécifier la hauteur ou les contraintes de l'UICollectionView afin qu'il soit clair que les cellules ne peuvent que défiler horizontalement et ne pas descendre jusqu'à la ligne suivante. La hauteur doit être identique ou légèrement supérieure à la hauteur de cellule que vous spécifiez à l'étape 2.

  2. Implémentez le délégué UICollectionViewDelegateFlowLayout et la méthode sizeForItemAt. Voici un exemple d'implémentation sizeForItemAt.

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let cellWidth = 100
        let cellHeight = 30
        return CGSize(width: cellWidth, height: cellHeight)
    }
    
0
craft