Comment créer une vue de collection simple avec Swift


188

J'essaye d'apprendre à utiliser UICollectionView. La documentation est un peu difficile à comprendre et les tutoriels que j'ai trouvés étaient soit en Objective C, soit en projets longs et compliqués.

Quand j'apprenais à utiliser UITableView, We ❤ Swift's How to make a simple tableview with iOS 8 and Swift avait une configuration et une explication très basiques pour me faire avancer. Y a-t-il quelque chose comme ça UICollectionView?

La réponse ci-dessous est ma tentative d'apprendre à faire cela.

Réponses:


515

Ce projet a été testé avec Xcode 10 et Swift 4.2.

Créer un nouveau projet

Il peut s'agir simplement d'une application à vue unique.

Ajouter le code

Créez un nouveau fichier Cocoa Touch Class (Fichier> Nouveau> Fichier ...> iOS> Cocoa Touch Class). Nommez-le MyCollectionViewCell. Cette classe contiendra les sorties pour les vues que vous ajoutez à votre cellule dans le storyboard.

import UIKit
class MyCollectionViewCell: UICollectionViewCell {
    
    @IBOutlet weak var myLabel: UILabel!
}

Nous connecterons cette prise plus tard.

Ouvrez ViewController.swift et assurez-vous que vous disposez du contenu suivant:

import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    
    let reuseIdentifier = "cell" // also enter this string as the cell identifier in the storyboard
    var items = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"]
    
    
    // MARK: - UICollectionViewDataSource protocol
    
    // tell the collection view how many cells to make
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.items.count
    }
    
    // make a cell for each cell index path
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        // get a reference to our storyboard cell
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MyCollectionViewCell
        
        // Use the outlet in our custom class to get a reference to the UILabel in the cell
        cell.myLabel.text = self.items[indexPath.row] // The row value is the same as the index of the desired text within the array.
        cell.backgroundColor = UIColor.cyan // make cell more visible in our example project
        
        return cell
    }
    
    // MARK: - UICollectionViewDelegate protocol
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        // handle tap events
        print("You selected cell #\(indexPath.item)!")
    }
}

Remarques

  • UICollectionViewDataSourceet UICollectionViewDelegatesont les protocoles que la vue de collection suit. Vous pouvez également ajouter le UICollectionViewFlowLayoutprotocole pour modifier la taille des vues par programme, mais ce n'est pas nécessaire.
  • Nous mettons juste des chaînes simples dans notre grille, mais vous pourrez certainement faire des images plus tard.

Configurer le storyboard

Faites glisser une vue de collection vers le contrôleur de vue de votre storyboard. Vous pouvez ajouter des contraintes pour qu'elle remplisse la vue parente si vous le souhaitez.

entrez la description de l'image ici

Assurez-vous que vos valeurs par défaut dans l'inspecteur d'attributs sont également

  • Articles: 1
  • Disposition: Flow

La petite boîte en haut à gauche de la vue de collection est une cellule de vue de collection. Nous l'utiliserons comme cellule prototype. Faites glisser une étiquette dans la cellule et centrez-la. Vous pouvez redimensionner les bordures de cellule et ajouter des contraintes pour centrer l'étiquette si vous le souhaitez.

entrez la description de l'image ici

Écrivez «cellule» (sans guillemets) dans la zone Identifiant de l'inspecteur d'attributs pour la cellule de vue de collection. Notez qu'il s'agit de la même valeur que let reuseIdentifier = "cell"dans ViewController.swift.

entrez la description de l'image ici

Et dans l'inspecteur d'identité de la cellule, définissez le nom de la classe sur MyCollectionViewCell, notre classe personnalisée que nous avons créée .

entrez la description de l'image ici

Branchez les prises

  • Accrochez l'étiquette de la cellule de collection à myLabella MyCollectionViewCellclasse. (Vous pouvez Ctrl-faire glisser .)
  • Accrochez la vue de collection delegateet dataSourcele contrôleur de vue. (Cliquez avec le bouton droit de la souris sur Vue de collection dans la structure du document. Ensuite, cliquez et faites glisser la flèche plus vers le haut vers le contrôleur de vue.)

entrez la description de l'image ici

Fini

Voici à quoi cela ressemble après avoir ajouté des contraintes pour centrer l'étiquette dans la cellule et épingler la vue de collection aux murs du parent.

entrez la description de l'image ici

Faire des améliorations

L'exemple ci-dessus fonctionne mais il est plutôt moche. Voici quelques éléments avec lesquels vous pouvez jouer:

Couleur de l'arrière plan

Dans l'Interface Builder, accédez à la vue de votre collection> Inspecteur d'attributs> Vue> Arrière-plan .

Espacement des cellules

La modification de l'espacement minimum entre les cellules à une valeur plus petite lui donne une meilleure apparence. Dans le générateur d'interface, accédez à votre vue de collection> Inspecteur de taille> Espacement minimum et réduisez les valeurs. «Pour les cellules» est la distance horizontale et «Pour les lignes» est la distance verticale.

Forme de cellule

Si vous voulez des coins arrondis, une bordure, etc., vous pouvez jouer avec la cellule layer. Voici un exemple de code. Vous le mettriez directement après cell.backgroundColor = UIColor.cyandans le code ci-dessus.

cell.layer.borderColor = UIColor.black.cgColor
cell.layer.borderWidth = 1
cell.layer.cornerRadius = 8

Voir cette réponse pour d'autres choses que vous pouvez faire avec le calque (ombre, par exemple).

Changer la couleur lorsque vous appuyez sur

Cela permet une meilleure expérience utilisateur lorsque les cellules répondent visuellement aux pressions. Une façon d'y parvenir est de changer la couleur d'arrière-plan pendant que la cellule est touchée. Pour ce faire, ajoutez les deux méthodes suivantes à votre ViewControllerclasse:

// change background color when user touches cell
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.red
}

// change background color back when user releases touch
func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.cyan
}

Voici le look mis à jour:

entrez la description de l'image ici

Une étude plus approfondie

Version UITableView de ce Q&R


1
im obtenant cell.myLabel comme nul et il plante. une idée pourquoi? J'utilise une mise en page personnalisée
Gerald

4
Si vous ne connectez pas la prise en faisant glisser le contrôle de l'étiquette dans le storyboard vers le code @IBOutletfor myLabelin, vous obtiendrez un plantage comme celui-ci.
Suragch le

3
si vous utilisez le générateur d'interface et référencez la cellule à l'aide d'une prise, n'enregistrez pas la classe de cellule personnalisée dans votre contrôleur. voir ça
Gerald

2
si la prise UICollectionViewCell est nulle, vous devez la supprimer self.collectionView.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: "Cell"). Si vous rencontrez toujours le problème, vérifiez s'il reuseIdentifiers'agit de la même chose dans dequeueReusableCellWithReuseIdentifieret dans le storyboard
Ashok R

42
Je souhaite que la documentation d'Apple soit aussi facile à lire que cette explication
elmarko

3

Délégués et sources de données de UICollectionView

//MARK: UICollectionViewDataSource

override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1     //return number of sections in collection view
}

override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10    //return number of rows in section
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("collectionCell", forIndexPath: indexPath)
    configureCell(cell, forItemAtIndexPath: indexPath)
    return cell      //return your cell
}

func configureCell(cell: UICollectionViewCell, forItemAtIndexPath: NSIndexPath) {
    cell.backgroundColor = UIColor.blackColor()


    //Customise your cell

}

override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
    let view =  collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "collectionCell", forIndexPath: indexPath) as UICollectionReusableView
    return view
}

//MARK: UICollectionViewDelegate
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
      // When user selects the cell
}

override func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
     // When user deselects the cell
}

3

Pour swift 4.2-

//MARK: UICollectionViewDataSource

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1     //return number of sections in collection view
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10    //return number of rows in section
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath as IndexPath)
    configureCell(cell: cell, forItemAtIndexPath: indexPath)
    return cell      //return your cell
}

func configureCell(cell: UICollectionViewCell, forItemAtIndexPath: NSIndexPath) {
    cell.backgroundColor = UIColor.black


    //Customise your cell

}

func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
    let view =  collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "collectionCell", for: indexPath as IndexPath) as UICollectionReusableView
    return view
}

//MARK: UICollectionViewDelegate
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    // When user selects the cell
}

func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
    // When user deselects the cell
}

1

L'implémentation d'UICollectionView est assez intéressante. Vous pouvez utiliser le code source simple et regarder un didacticiel vidéo en utilisant ces liens:

https://github.com/Ady901/Demo02CollectionView.git

https://www.youtube.com/watch?v=5SrgvZF67Yw

extension ViewController : UICollectionViewDataSource {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return nameArr.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DummyCollectionCell", for: indexPath) as! DummyCollectionCell
        cell.titleLabel.text = nameArr[indexPath.row]
        cell.userImageView.backgroundColor = .blue
        return cell
    }

}

extension ViewController : UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let alert = UIAlertController(title: "Hi", message: "\(nameArr[indexPath.row])", preferredStyle: .alert)
        let action = UIAlertAction(title: "OK", style: .default, handler: nil)
        alert.addAction(action)
        self.present(alert, animated: true, completion: nil)
    }

}

0

UICollectionView est identique à UITableView mais il nous donne la fonctionnalité supplémentaire de créer simplement une vue de grille, ce qui est un peu problématique dans UITableView. Ce sera un très long post, je mentionne un lien à partir duquel vous obtiendrez tout en quelques étapes simples.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.