1

Ich brauche eine Auflistungsansicht, die Zellen in einem Raster anzeigt. Also ein Standard-Flow-Layout ist in Ordnung für mich. Ich möchte jedoch angeben, wie viele Zellen pro Zeile angezeigt werden sollen, während die Zellenhöhe durch die automatischen Layoutbeschränkungen bestimmt werden sollte, die ich in die Zelle einfüge. Hier ist meine Zelle Layout:Ermitteln der UICollectionView-Zellenhöhe nur durch das automatische Layout

enter image description here

Es ist ganz einfach - eine Bildansicht und zwei Etiketten darunter. Jetzt hat die Bildansicht eine Seitenverhältniseinschränkung (1: 1), was bedeutet, dass, wenn die Breite für die Zelle bekannt ist, die Höhe automatisch durch die automatischen Layoutregeln bekannt sein sollte (es gibt vertikale Beschränkungen, die durchgehen: cellop-image-label1 -label2-cellbottom).

Jetzt, da ich weiß, keine andere gute Möglichkeit, die Sammlung Ansicht zu sagen 2 Artikel zeigen pro Zeile habe ich UICollectionViewDelegateFlowLayout Methoden außer Kraft gesetzt:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
    let availableWidth = collectionView.frame.width - padding 
    let widthPerItem = availableWidth/itemsPerRow 

    return CGSize(width: widthPerItem, height: widthPerItem) 
} 

Wie Sie sehen können, da ich nicht‘ Wenn ich die Höhe des Gegenstands kenne, gebe ich dasselbe wie die Breite zurück, in der Hoffnung, dass das automatische Layout das Problem später beheben wird. Ich setze auch die estimatedItemSize, damit der ganze Mechanismus zu arbeiten beginnt.

Die Ergebnisse sind recht seltsam - es scheint, wie die Sammlung View-Event findet nicht berücksichtigt die Breite ich dorthin zurückkehren, vor allem auf die Etikettenlängen abhängig:

enter image description here

ich einige andere gesehen haben Antworten, wo Leute empfehlen, die Zelle Größe für die Breite manuell zu berechnen, wie sagen "Layout selbst, dann messen Sie sich, dann geben Sie mir Ihre Größe für diese Breite", und obwohl es noch die Auto-Layout-Regeln unter der Haube laufen würde, würde ich gerne wissen, ob es eine Möglichkeit gibt, dies zu tun, ohne die Größe manuell zu ändern.

Antwort

0

Sie können ganz einfach die Höhe Ihrer Collection Zelle in der Größe Inspektors Storyboard finden Sie heraus, wie unten dargestellt:

enter image description here

nun gerade diese Höhe abholen von hier, und an den außer Kraft gesetzt passieren UICollectionViewDelegateFlowLayout Methode:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
    let availableWidth = collectionView.frame.width - padding 
    let widthPerItem = availableWidth/itemsPerRow 

    return CGSize(width: widthPerItem, height: **114**) 
} 

Und Sie werden um die gewünschte Ausgabe zu erhalten.

+0

Ich wollte alles durch Autolayout behandelt werden, plus die hardcoded Höhe wird nicht funktionieren, da die tatsächliche Höhe für verschiedene Bildschirmgrößen unterschiedlich sein wird. – frangulyan

0

Ich habe schließlich einen Trick implementiert, um alles auf das automatische Layout zu verschieben. Ich habe die delegate-Methode func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize komplett entfernt und im Interface-Builder eine Breitenbeschränkung für meinen Zelleninhalt hinzugefügt (setze den Anfangswert auf etwas, das ist nicht wichtig). Dann habe ich einen Auslass für diese Einschränkung in der kundenspezifischen Zellklasse:

class MyCell: UICollectionViewCell { 

    @IBOutlet weak var cellContentWidth: NSLayoutConstraint! 

    func updateCellWidth(width: CGFloat) { 
     cellContentWidth.constant = width 
    } 
} 

Später, wenn die Zelle angelegt wird, I die Breite Einschränkung der vorberechneten Wert Stand entsprechend der Anzahl der Zellen, die I pro Reihe wollen :

private var cellWidth: CGFloat { 
    let paddingSpace = itemSpacing * (itemsPerRow - 1) + sectionInsets.left + sectionInsets.right 
    let availableWidth = collectionView.frame.width - paddingSpace 
    return availableWidth/itemsPerRow 
} 

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! MyCell 

    ... 

    cell.updateCellWidth(width: cellWidth) 

    return cell 
} 

Und dies, zusammen mit Auto-Layout-Zellengröße aktiviert, wird die Zellen richtig auslegen.

Verwandte Themen