Recherche…


Créer une vue de collection par programme

Rapide

func createCollectionView() {
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height), collectionViewLayout: layout)
    collectionView.dataSource = self
    collectionView.delegate = self
    view.addSubview(collectionView)
}

Objectif c

- (void)createCollectionView {
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) collectionViewLayout:layout];
    [collectionView setDataSource:self];
    [collectionView setDelegate:self];
    [self.view addSubview:collectionView];
}

Swift - UICollectionViewDelegateFlowLayout

// MARK: - UICollectionViewDelegateFlowLayout
extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        return CGSize(width: 50, height: 50)
    }
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
    }
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 5.0
    }
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 5.0
    }
}

Créer une UICollectionView

Initialiser un UICollectionView avec un cadre CGRect :

Rapide:

let collection = UICollectionView(frame: CGRect(x: 0, y: 0, width: 200, height: 21))

Objectif c:

UICollectionView *collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 200, 21)];

Vous pouvez également créer un UICollectionView dans Interface Builder

entrer la description de l'image ici

UICollectionView - Source de données

Chaque vue de collection doit avoir un objet Datasource . L'objet Datasource est le contenu que votre application affichera dans UICollectionView . Au minimum, tous les objets Datasource doivent implémenter collectionView:numberOfItemsInSection: et collectionView:cellForItemAtIndexPath: méthodes.

Méthodes requises

Rapide

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // Return how many items in section
    let sectionArray = _data[section]
    return sectionArray.count
}
    
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

   let cell = collectionView.dequeueReusableCellWithReuseIdentifier(MyCellID) 
   // If you use a custom cell class then cast the cell returned, like:
   // as! MyCollectionViewCellClass
   // or you will have errors when you try to use features of that class.

   //Customize your cell here, default UICollectionViewCells do not contain any inherent
   //text or image views (like UITableView), but some could be added, 
   //or a custom UICollectionViewCell sub-class could be used
   return cell
}

Objectif c

- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section {
    // Return how many items in section
    NSArray *sectionArray = [_data objectAtIndex:section];
    return [sectionArray count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath {
   // Return a cell
   UICollectionViewCell *newCell = [self.collectionView 
                                       dequeueReusableCellWithReuseIdentifier:MyCellID                                                                             
                                                                 forIndexPath:indexPath];
   //Customize your cell here, default UICollectionViewCells do not contain any inherent
   //text or image views (like UITableView), but some could be added, 
   //or a custom UICollectionViewCell sub-class could be used
   return newCell;
}

Exemple de base Swift d'une vue de collection

Créer un nouveau projet

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

Ajouter le code

Créez un nouveau fichier Cocoa Touch Class (Fichier> Nouveau> Fichier ...> iOS> Classe Cocoa Touch). 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 allons connecter cette prise plus tard.

Ouvrez ViewController.swift et assurez-vous d'avoir le 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, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        
        // get a reference to our storyboard cell
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: 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.item]
        cell.backgroundColor = UIColor.yellowColor() // make cell more visible in our example project
        
        return cell
    }
    
    // MARK: - UICollectionViewDelegate protocol
    
    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        // handle tap events
        print("You selected cell #\(indexPath.item)!")
    }
}

Remarques

  • UICollectionViewDataSource et UICollectionViewDelegate sont les protocoles que la vue de collection suit. Vous pouvez également ajouter le protocole UICollectionViewDelegateFlowLayout pour modifier la taille des vues par programmation, mais cela n'est pas nécessaire.
  • Nous mettons simplement des chaînes simples dans notre grille, mais vous pouvez 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 le faire remplir la vue parent si vous le souhaitez.

Ajout de la vue de la collection à la capture d'écran du storyboard

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

  • Articles: 1
  • Mise en page: flux

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

capture d'écran collection view label

Ecrivez "cellule" (sans guillemets) dans la zone Identifiant de l'inspecteur d'attributs pour la cellule de vue de collection. Notez que c'est la même valeur que let reuseIdentifier = "cell" dans ViewController.swift.

réglage de la cellule

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

paramétrage du nom de la classe de cellule personnalisée

Brancher les sorties

  • Accrochez l'étiquette dans la cellule de collection à myLabel dans la classe MyCollectionViewCell . (Vous pouvez faire glisser le curseur .)
  • Accrochez le delegate et le dataSource du View View au View Controller. (Cliquez avec le bouton droit de la souris sur la vue Collection dans la structure du document. Cliquez ensuite sur la flèche et faites-la glisser jusqu'au View Controller.)

capture d'écran du délégué et des sorties de source de données

Fini

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

capture d'écran du résultat final

Faire des améliorations

Si vous souhaitez apporter des améliorations à l'apparence, reportez-vous à la publication d'origine de cet exemple .

vue de collection avec capture d'écran améliorée

Une étude plus approfondie

Effectuer des mises à jour par lots

Vous pouvez animer des modifications complexes dans votre vue de collection à l'aide de la méthode performBatchUpdates . A l'intérieur du bloc de mise à jour, vous pouvez spécifier plusieurs modifications pour les animer en une seule fois.

collecitonView.performBatchUpdates({
    // Perform updates
}, nil)

Dans le bloc de mise à jour, vous pouvez effectuer des insertions, des suppressions, des déplacements et des rechargements. Voici comment déterminer quel indexPath utiliser:

Type NSIndexPath
Insertion Index dans un nouveau tableau
Effacement Index dans l'ancien tableau
Bouge toi de: ancien tableau, à: nouveau tableau
Recharger soit nouveau ou ancien tableau (cela ne devrait pas avoir d'importance)

Vous ne devez appeler que le rechargement sur les cellules qui n'ont pas été déplacées, mais leur contenu a changé. Il est important de noter qu'un déplacement ne rafraîchit pas le contenu d'une cellule, mais déplace uniquement son emplacement.

Pour vérifier que votre mise à jour par lots sera effectuée correctement, assurez-vous que l'ensemble d'indexPaths pour la deletion , le move-from et le reload est unique et que l'ensemble d'indexPaths pour l' insertion , le move-to et le reload est unique.

Voici un exemple de mise à jour de lot correcte:

let from = [1, 2, 3, 4, 5]
let to = [1, 3, 6, 4, 5]

collecitonView.performBatchUpdates({
    collectionView.insertItemsAtIndexPaths([NSIndexPath(forItem: 2, inSection: 0)])
    collectionView.deleteItemsAtIndexPaths([NSIndexPath(forItem: 1, inSection: 0)])
    collectionView.moveItemAtIndexPath(NSIndexPath(forItem: 2, inSection: 0), 
                                       toIndexPath: NSIndexPath(forItem: 1, inSection:0))
}, nil)

Configuration de UICollectionViewDelegate et sélection des éléments

Parfois, si une action doit être liée à la sélection de cellules d'une vue de collection, vous devez implémenter le protocole UICollectionViewDelegate .

Supposons que la vue de collection se trouve dans un UIViewController MyViewController .

Objectif c

Dans votre MyViewController.h déclare qu'il implémente le protocole UICollectionViewDelegate , comme ci-dessous

@interface MyViewController : UIViewController <UICollectionViewDelegate, .../* previous existing delegate, as UICollectionDataSource *>

Rapide

Dans votre MyViewController.swift, ajoutez ce qui suit

class MyViewController : UICollectionViewDelegate {
}

La méthode à mettre en œuvre est

Objectif c

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
}

Rapide

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
}

À titre d'exemple, nous pouvons définir la couleur d'arrière-plan de la cellule sélectionnée sur verte.

Objectif c

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
    cell.backgroundColor = [UIColor greenColor];
}

Rapide

class MyViewController : UICollectionViewDelegate {
    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
    {
        var cell : UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
        cell.backgroundColor = UIColor.greenColor()
    }
}

Gérer plusieurs vues de collection avec DataSource et Flowlayout

Ici, nous gérons plusieurs méthodes de délégation de collections avec des événements de Didselect.

extension ProductsVC: UICollectionViewDelegate, UICollectionViewDataSource{
        
        // MARK: - UICollectionViewDataSource
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            guard collectionView == collectionCategory else {
                return arrOfProducts.count
            }
            return arrOfCategory.count
        }
        
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            
            guard collectionView == collectionProduct else {
                  let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProductCategoryCell", for: indexPath) as! ProductCategoryCell
                  cell.viewBackground.layer.borderWidth = 0.5
                  //Do some thing as per use
                  return cell
            }
            
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ProductCell
            cell.contentView.layer.borderWidth = 0.5
            cell.contentView.layer.borderColor = UIColor.black.cgColor
            let json = arrOfProducts[indexPath.row]
            //Do something as per use
    
            return cell
        }
        
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            guard collectionView == collectionCategory else {
                let json = arrOfProducts[indexPath.row]
                // Do something for  collectionProduct here
                return
            }
            let json = arrOfCategory[indexPath.row] as [String: AnyObject]
            let id = json["cId"] as? String ?? ""
            // Do something
        }
    }
    
    extension ProductsVC: UICollectionViewDelegateFlowLayout{
        
        // MARK: - UICollectionViewDelegateFlowLayout
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            
            let collectionWidth = collectionView.bounds.width
            guard collectionView == collectionProduct else {
                var itemWidth = collectionWidth / 4 - 1;
                
                if(UI_USER_INTERFACE_IDIOM() == .pad) {
                    itemWidth = collectionWidth / 4 - 1;
                }
                return CGSize(width: itemWidth, height: 50)
            }
            
            var itemWidth = collectionWidth / 2 - 1;
            if(UI_USER_INTERFACE_IDIOM() == .pad) {
                itemWidth = collectionWidth / 4 - 1;
            }
            return CGSize(width: itemWidth, height: 250);
        }
        
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
            return 1
        }
        
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
            return 1
        }
        
    }

vues de collection



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow