web-dev-qa-db-fra.com

Comment créer l'en-tête et le pied de page dans uicollectionview avec swift

Comment créer à la fois l'en-tête et le pied de page dans la vue Collection dans Swift?

J'essaie de combiner un en-tête et un pied de page, mais cela ne cesse de planter, je ne trouve pas le didacticiel Swift pour le comprendre.

Je ne sais pas comment retourner une vue supplémentaire pour les deux, mais une seule.

Je les mets tous les deux sur le storyboard (classe + identifiant) 

 override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    //#warning Incomplete method implementation -- Return the number of sections
    return 2
}


override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //#warning Incomplete method implementation -- Return the number of items in the section
    return 10
}




override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
    var header: headerCell!
    var footer: footerCell!



    if kind == UICollectionElementKindSectionHeader {
        header =
            collectionView.dequeueReusableSupplementaryViewOfKind(kind,
                withReuseIdentifier: "header", forIndexPath: indexPath)
            as? headerCell

}
    return header

}

Erreur: UICollectionElementKindCell avec l'identificateur numéro un - doit enregistrer un nib ou une classe pour l'identificateur ou connecter une cellule prototype dans un storyboard '

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> profileCC {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("one", forIndexPath: indexPath) as! profileCC

    // Configure the cell

    return cell
}



override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {

    switch kind {

    case UICollectionElementKindSectionHeader:

        let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "header", forIndexPath: indexPath) as! headerCell

        headerView.backgroundColor = UIColor.blueColor();
        return headerView

    case UICollectionElementKindSectionFooter:
        let footerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "footer", forIndexPath: indexPath) as! footerCell

        footerView.backgroundColor = UIColor.greenColor();
        return footerView

    default:

        assert(false, "Unexpected element kind")
    }
}

J'espère que quelqu'un va aider.

29
marrioa

Vous pouvez définir une UICollectionViewController pour gérer la UICollectionView et dans Interface Builder activer les sections Pied de page et En-tête , puis utiliser la méthode suivante pour prévisualiser UICollectionView les deux sections ajoutées:

override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {

    switch kind {

    case UICollectionView.elementKindSectionHeader:

        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Header", for: indexPath)

        headerView.backgroundColor = UIColor.blue
        return headerView

    case UICollectionView.elementKindSectionFooter:
        let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Footer", for: indexPath)

        footerView.backgroundColor = UIColor.green
        return footerView

    default:

        assert(false, "Unexpected element kind")
    }

Dans le code ci-dessus, je mets la identifier pour le pied de page et l'en-tête sous la forme Header et Footer par exemple, vous pouvez le faire à votre guise. Si vous souhaitez créer un en-tête ou un pied de page personnalisé, vous devez créer une sous-classe de UICollectionReusableView pour chacun et le personnaliser à votre guise.

Vous pouvez enregistrer vos classes de pied de page et d'en-tête personnalisées dans Interface Builder ou dans le code de la manière suivante:

registerClass(myFooterViewClass, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "myFooterView")
57
Victor Sigler

Mis à jour pour Swift 3+

Étape 1:  

Dans votre classe de contrôleur de vue, enregistrez la classe à utiliser comme en-tête, pied de page ou les deux:

let collectionViewHeaderFooterReuseIdentifier = "MyHeaderFooterClass"

Étape 2:

Si vous utilisez un xib, utilisez:

collectionView.register(UINib(nibName: collectionViewHeaderFooterReuseIdentifier bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier:collectionViewHeaderFooterReuseIdentifier)

collectionView.register(UINib(nibName: collectionViewHeaderFooterReuseIdentifier bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier:collectionViewHeaderFooterReuseIdentifier)

Si vous n'utilisez pas xib:

collectionView.register(MyHeaderFooterClass.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier)

collectionView.register(MyHeaderFooterClass.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier)

Étape 3:

Créez une classe d'en-tête/pied de page personnalisée, l'implémentation se présente comme suit:

import UIKit

class MyHeaderFooterClass: UICollectionReusableView {

 override init(frame: CGRect) {
    super.init(frame: frame)
    self.backgroundColor = UIColor.purple

    // Customize here

 }

 required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

 }
}

Étape 4: Si vous n'utilisez pas xib, ignorez

  • Créez une nouvelle xib vide: "Fichier -> Nouveau fichier -> Vide".

  • Nommez-le exactement le même nom que la classe. Dans cet exemple: "MyHeaderFooterClass"

  • Ajoutez une vue réutilisable de la collection à la xib.
  • Cliquez sur cet objet, sélectionnez l'inspecteur d'identité et changez la classe de cet objet en "MyHeaderFooterClass".

Étape 5: - Soutenez cette nouvelle cellule dans votre vue de collection via la méthode du délégué:

 func collectionView(_ collectionView: UICollectionView,
                    viewForSupplementaryElementOfKind kind: String,
                    at indexPath: IndexPath) -> UICollectionReusableView {

    switch kind {

    case UICollectionElementKindSectionHeader:
        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier, for: indexPath)

        headerView.backgroundColor = UIColor.blue
        return headerView

    case UICollectionElementKindSectionFooter:
        let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier, for: indexPath)

        footerView.backgroundColor = UIColor.green
        return footerView

    default:
        assert(false, "Unexpected element kind")
    }
}
11
mobilecat

Pour compléter les réponses restantes, n'oubliez pas d'allouer de l'espace pour vos vues d'en-tête/pied de page, sinon collectionView:viewForSupplementaryElementOfKind:atIndexPath ne sera pas appelé .

Faites-le en implémentant collectionView:layout:referenceSizeForHeaderInSection dans votre source de données collectionView.

4
Bruno Cunha

Solution

class CustomFlowLayout: UICollectionViewFlowLayout {

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
        var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()

        for attributes in attributesForElementsInRect! {

            if !(attributes.representedElementKind == UICollectionElementKindSectionHeader
                || attributes.representedElementKind == UICollectionElementKindSectionFooter) {

                // cells will be customise here, but Header and Footer will have layout without changes.
            }

            newAttributesForElementsInRect.append(attributes)
        }

        return newAttributesForElementsInRect
    }
}


class YourViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let headerNib = UINib.init(nibName: "HeaderCell", bundle: nil)
        collectionView.register(headerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderCell")

        let footerNib = UINib.init(nibName: "FooterCell", bundle: nil)
        collectionView.register(footerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "FooterCell")
    }


    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        switch kind {
        case UICollectionElementKindSectionHeader:
            let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
            return headerView
        case UICollectionElementKindSectionFooter:
            let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FooterCell", for: indexPath) as! FooterCell
            return footerView
        default:
            return UICollectionReusableView()
        }
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: 45)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: 25)
    }
}
1
Zanael

Après avoir utilisé le code @mobilecat, vous devriez utiliser cette fonction pour faire apparaître l'en-tête et le pied de page.

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: 180.0)
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
        return CGSize(width: 60.0, height: 30.0)
    }
0
Ahmed Abdallah