webentwicklung-frage-antwort-db.com.de

UICollectionView Mehrere Abschnitte und Kopfzeilen

Ich habe Schwierigkeiten, mehrere Abschnitte in meiner Sammlungsansicht mit einem Header für jeden Abschnitt zu erstellen. Ich kenne Obj-C nicht und ich habe eine Menge Tutorials dafür gefunden, aber ich habe nicht herausgefunden, wie man es in Swift umwandeln kann. 

Alle meine Daten sind statisch, also brauche ich nur ein Array oder ein Wörterbuch, mit dem ich mehrere Abschnitte erstellen kann. Ich habe bereits eine Sammlungsansicht, in der 1 Abschnitt funktioniert. Wenn Sie also Einblick oder Code für mehrere Abschnitte haben, wäre das hilfreich. 

Ich weiß, wie man mehrere Abschnitte mit einstellt 

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int   {
    return sectionData.count
}

Ich denke, die Hauptsache, bei der ich Hilfe brauche, ist die Implementierung dieser Funktion

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { }

und die Daten einrichten! 

UICollectionView und UITableView sind fast identisch. Wenn Sie also wissen, wie Sie mehrere Abschnitte in einer UITableView in Swift ausführen, wird Ihre Hilfe ebenfalls geschätzt

13
user3399235

Die cellForItemAtIndexPath-Funktion behandelt das Ausfüllen jedes Abschnitts mit Zellen. Es behandelt keine Abschnitte oder ergänzende Ansichten. Daher ist es nicht die Hauptsache, die Sie beim Erstellen von Abschnittskopfzeilen benötigen. 

die Methode, die Sie implementieren müssen, ist viewForSupplementaryElementOfKind. Ihre Unterschrift lautet: 

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

Unter der Annahme, dass Ihre collectionView für einen Abschnitt ordnungsgemäß funktioniert (Sie haben den Body Ihres cellForItemAtIndexPath richtig ausgefüllt und Ihr sectionData-Array die Anzahl der anzuzeigenden Abschnitte richtig wiedergegeben), sollten Sie in der Lage sein, Abschnittsheader mit den folgenden Zeigern zu implementieren: 

Neben Zellen unterstützt UICollectionView auch "ergänzende" Ansichtsobjekte, die normalerweise für Kopf- oder Fußzeilen verwendet werden. Diese ergänzenden Ansichten verhalten sich sehr ähnlich wie UICollectionViewCell-Objekte. Auf dieselbe Weise wie cellForItemAtIndexPath Zellen behandelt, behandelt die Funktion viewForSupplementaryElementOfKind ergänzende Ansichten. 

Um dies zu implementieren, müssen Sie zunächst Ihren ViewController darauf vorbereiten. Bearbeiten Sie zunächst Ihr Layoutobjekt, um eine geeignete Kopfgröße anzuzeigen, die jeder Kopf einhält:

 let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
 layout.headerReferenceSize = CGSize(width: self.view.frame.size.width, height: 30)

HINWEIS: Ich verwende ein UICollectionViewFlowLayout

Wenn Sie dies noch nicht getan haben, erstellen Sie als Nächstes eine SectionHeader-Klasse, die jedes Abschnittsheaderobjekt definiert. Sie können diese Klasse dann mit Ihrem collectionView-Objekt wie folgt registrieren:

  collectionView!.registerClass(SectionHeaderView.self, forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: "SectionHeaderView");

Das erste und das dritte übergebene Argument entsprechen hier der Registrierung einer UICollectionViewCell-Klasse. Das erste Argument in dieser Methode ist der Verweis auf die von Ihnen erstellte Abschnittsheaderklasse. Die dritte ist die Wiederverwendungskennung für die Ergänzungsansicht. 

Das zweite Argument ist spezifisch für Supplementary Views. Dies setzt kind der SupplementaryView. Hierbei handelt es sich um einen Header, für den die konstante Zeichenfolge der UICollectionViewFlowLayout-Klasse UICollectionElementKindSectionHeader verwendet wird. Wenn Sie die Parameter in der Variablen viewForSupplementaryElementOfKind bemerkt haben, wird diese kind später als Parameter kind: String übergeben. 

Füllen Sie den Rumpf Ihrer viewForSupplementaryElementOfKind auf dieselbe Weise wie bei einer cellForItemAtIndexPath-Funktion. Erstellen Sie mit der dequeueReusableSupplementaryViewOfKind-Methode ein SectionHeader-Objekt, legen Sie gegebenenfalls die erforderlichen Attribute (Beschriftungen, Farben usw.) fest und geben Sie das Header-Objekt zurück. 

Hoffe das hilft!!

Referenzpunkte: 

https://developer.Apple.com/library/prerelease/ios/documentation/UIKit/Reference/UICollectionViewDataSource_protocol/index.html#//Apple_ref/occ/intfm/UICollectionViewDataSource/

https://developer.Apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewFlowLayout_class/index.html#//Apple_ref/c/data/UICollectionElementKindSectionHeade

14
mkncode

Hier ist der Code, der für mich funktioniert hat

erstellen Sie die Kopfzelle. Dazu habe ich eine benutzerdefinierte Zellklasse und eine Spitze erstellt, um die Anpassung der Zelle im Grafikeditor vorzunehmen

Fügen Sie in viewDidLoad Folgendes hinzu

self.collectionView?.registerNib(UINib(nibName: "KlosetCollectionHeaderViewCell", bundle: nil), forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderCell")

Dann fügen Sie die Delegatfunktion hinzu

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

    let headerCell = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "HeaderCell", forIndexPath: indexPath) as? KlosetCollectionHeaderViewCell    

    return headerCell!
  }

Dadurch wird die HeaderCell in die SectionView der PFCollectionView eingefügt. Die Steuerelemente, die in der Zelle angezeigt werden, die Sie der xib-Datei hinzufügen, sowie die Ausgänge und Aktionen

4
lguerra10

Nach dem Erstellen und Registrieren von benutzerdefinierten Kopfzeilen (und/oder Fußzeilen) können Sie problemlos unterschiedliche Kopfzeilen (oder Fußzeilen für diese Angelegenheit) für verschiedene Abschnitte angeben. Hier ist ein Beispiel:

    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        switch kind {
        case UICollectionElementKindSectionHeader:
            let section = indexPath.section

            switch section {
            case 0:
                let userHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: homeHeaderReuseIdentifier, for: indexPath) as! UserHeader
                return userHeader
            default:
                let postHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: sectionSpacingHeaderReuseIdentifier, for: indexPath) as! PostHeader
                return postHeader
            }
        case UICollectionElementKindSectionFooter:
            let userFooter = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: homeFooterReuseIdentifier, for: indexPath) as! UserFooter
            return userFooter
        default:
            return UICollectionReusableView()
        }
    }

Stellen Sie sicher, dass Sie auch die korrekte Anzahl der Abschnitte angeben:

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

Definieren Sie Ihre UICollectionViewCell als Kopfansicht der Art. UICollectionElementKindSectionHeader - In meinem Fall habe ich zwei Header - OfferHeaderCell und APRHeaderCell, die wie folgt definiert sind:

verticalCollectionView.register(UINib(nibName: "OfferHeaderCell", bundle: nil), forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: "OfferHeaderCell")
verticalCollectionView.register(UINib(nibName: "APRHeaderCell", bundle: nil), forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: "APRHeaderCell")

Fahren Sie fort und geben Sie für jeden Abschnitt einen Header zurück. Legen Sie dann in dieser UICollectionViewDelegateFlowLayout-Funktion die Größe des Section-Headers auf Null fest

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    if(section==0) {
        return CGSize.zero
    } else if (section==1) {
        return CGSize(width:collectionView.frame.size.width, height:133)
    } else {
        return CGSize(width:collectionView.frame.size.width, height:100)
    }

}

Wichtig, das viewForSupplementaryElementOfKind für zwei verschiedene Abschnitte wie folgt zu definieren:

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

    var reusableview = UICollectionReusableView()
    if (kind == UICollectionElementKindSectionHeader) {
        let section = indexPath.section
        switch (section) {
        case 1:
            let  firstheader: OfferHeaderCell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "OfferHeaderCell", for: indexPath) as! OfferHeaderCell
            reusableview = firstheader
        case 2:
            let  secondHeader: APRHeaderCell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "APRHeaderCell", for: indexPath) as! APRHeaderCell
            reusableview = secondHeader
        default:
            return reusableview

        }
    }
    return reusableview
}

Und schließlich die Datenquelle,

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

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if (section==2) {
        return 2
    }
    return 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = verticalCollectionView.dequeueReusableCell(withReuseIdentifier: "ReviseOfferCell", for: indexPath)
    cell.backgroundColor = UIColor.white
    return cell
}

Anmerkung: Vergessen Sie nicht, UICollectionFlowLayout wie folgt hinzuzufügen:

// MARK: UICollectionViewDelegateFlowLayout

extension MakeAnOfferController: UICollectionViewDelegateFlowLayout {

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

            if indexPath.item == 0 {
                return CGSize(width: self.view.frame.size.width, height: 626.0)
            }
            return CGSize()
        }

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

            if(section==0) {
                return CGSize.zero
            } else if (section==1) {
                return CGSize(width:collectionView.frame.size.width, height:133)
            } else {
                return CGSize(width:collectionView.frame.size.width, height:100)
            }
        }
    }
1
Tarun

@ Taruns Antwort war ein Leckerbissen für mich; Mir fehlte collectionView(_:layout:referenceSizeForHeaderInSection:), was ich brauchte, da manchmal die angezeigten Daten sortiert wurden und manchmal nicht.

Darüber hinaus wurde das Übertragen des Abschnittskopfs an den oberen Rand des Bildschirms (wie in der Tabellensicht Apples Adressbuch-App von Apple) durch Hinzufügen des folgenden Elements zu viewDidLoad() im UICollectionViewController ausgeführt:

if let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout {
    flowLayout.sectionHeadersPinToVisibleBounds = true
}
0
Glenn

Funktionierte Lösung für Swift-3 

i) Erstelle benutzerdefinierte Zelle && entsprechendes Xib

   class SectionHeaderView: UICollectionViewCell {
        static let kReuseIdentifier = "SectionHeaderView"
        @IBOutlet weak var invitationsSectionHeader: UILabel!
        @IBOutlet weak var numberOfPerson: UILabel!
 }

ii) Registrieren Sie die Ansichtszelle für benutzerdefinierte Sammlungen für HeaderView

 self.collectionView.register(UINib(nibName: SectionHeaderView.kReuseIdentifier, bundle: nil), forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: SectionHeaderView.kReuseIdentifier)

iii) Rufen Sie die Delegatfunktion auf, um die benutzerdefinierte Kopfansicht anzuzeigen.

  func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        switch kind {
        case UICollectionElementKindSectionHeader:
           let  headerView: SectionHeaderView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: SectionHeaderView.kReuseIdentifier, for: indexPath) as! SectionHeaderView
            return headerView
        default:
            return UICollectionReusableView()
        }
    }

iv) Höhe der Erwähnung der benutzerdefinierten Kopfansicht

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