Aktualisiert für Swift 5
preferredLayoutAttributesFittingAttributes
umbenannt in preferredLayoutAttributesFitting
und verwenden Sie die automatische Größenanpassung
Aktualisiert für Swift 4
systemLayoutSizeFittingSize
umbenannt in systemLayoutSizeFitting
Aktualisiert für iOS 9
Nachdem ich gesehen hatte, dass meine GitHub-Lösung unter iOS 9 kaputt ging, hatte ich endlich die Zeit, das Problem vollständig zu untersuchen. Ich habe das Repo jetzt aktualisiert und einige Beispiele für verschiedene Konfigurationen für Zellen mit Selbstgröße hinzugefügt. Mein Fazit ist, dass Zellen mit Selbstgröße theoretisch großartig, in der Praxis jedoch chaotisch sind. Ein Wort der Vorsicht, wenn Sie mit Zellen mit Selbstgröße fortfahren.
TL; DR
Schauen Sie sich mein GitHub-Projekt an
Zellen mit Selbstgröße werden nur mit Ablauflayout unterstützt. Stellen Sie daher sicher, dass Sie diese verwenden.
Es gibt zwei Dinge, die Sie einrichten müssen, damit Zellen mit Selbstgröße funktionieren.
1. Stellen Sie estimatedItemSize
aufUICollectionViewFlowLayout
Das Flow-Layout wird von Natur aus dynamisch, sobald Sie die estimatedItemSize
Eigenschaft festlegen .
self.flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
2. Fügen Sie Unterstützung für die Größenbestimmung in Ihrer Zellunterklasse hinzu
Dies kommt in 2 Geschmacksrichtungen; Auto-Layout oder benutzerdefinierte Überschreibung von preferredLayoutAttributesFittingAttributes
.
Erstellen und konfigurieren Sie Zellen mit Auto Layout
Ich werde nicht näher darauf eingehen, da es einen brillanten SO-Beitrag zum Konfigurieren von Einschränkungen für eine Zelle gibt. Seien Sie nur vorsichtig, dass Xcode 6 mit iOS 7 eine Reihe von Problemen gelöst hat. Wenn Sie also iOS 7 unterstützen, müssen Sie beispielsweise sicherstellen, dass die Autoresizing-Maske in der Inhaltsansicht der Zelle festgelegt ist und dass die Grenzen der Inhaltsansicht als die Grenzen der Zelle festgelegt werden, wenn Die Zelle wird geladen (dh awakeFromNib
).
Was Sie beachten müssen, ist, dass Ihre Zelle stärker eingeschränkt werden muss als eine Zelle mit Tabellenansicht. Wenn Sie beispielsweise möchten, dass Ihre Breite dynamisch ist, benötigt Ihre Zelle eine Höhenbeschränkung. Wenn Sie möchten, dass die Höhe dynamisch ist, benötigen Sie ebenfalls eine Breitenbeschränkung für Ihre Zelle.
Implementieren Sie preferredLayoutAttributesFittingAttributes
in Ihrer benutzerdefinierten Zelle
Wenn diese Funktion aufgerufen wird, wurde Ihre Ansicht bereits mit Inhalten konfiguriert (dh cellForItem
aufgerufen). Unter der Annahme, dass Ihre Einschränkungen angemessen festgelegt wurden, könnten Sie eine Implementierung wie diese haben:
//forces the system to do one layout pass
var isHeightCalculated: Bool = false
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
//Exhibit A - We need to cache our calculation to prevent a crash.
if !isHeightCalculated {
setNeedsLayout()
layoutIfNeeded()
let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
var newFrame = layoutAttributes.frame
newFrame.size.width = CGFloat(ceilf(Float(size.width)))
layoutAttributes.frame = newFrame
isHeightCalculated = true
}
return layoutAttributes
}
HINWEIS Unter iOS 9 hat sich das Verhalten etwas geändert, was zu Abstürzen Ihrer Implementierung führen kann, wenn Sie nicht vorsichtig sind (weitere Informationen finden Sie hier ). Bei der Implementierung müssen preferredLayoutAttributesFittingAttributes
Sie sicherstellen, dass Sie den Rahmen Ihrer Layoutattribute nur einmal ändern. Wenn Sie dies nicht tun, ruft das Layout Ihre Implementierung auf unbestimmte Zeit auf und stürzt schließlich ab. Eine Lösung besteht darin, die berechnete Größe in Ihrer Zelle zwischenzuspeichern und diese jedes Mal ungültig zu machen, wenn Sie die Zelle wiederverwenden oder ihren Inhalt ändern, wie ich es mit der isHeightCalculated
Eigenschaft getan habe .
Erleben Sie Ihr Layout
Zu diesem Zeitpunkt sollten in Ihrer collectionView "funktionierende" dynamische Zellen vorhanden sein. Ich habe die Out-of-the-Box-Lösung während meiner Tests noch nicht als ausreichend befunden. Wenn Sie dies getan haben, können Sie dies gerne kommentieren. Es fühlt sich immer noch so an, als würde UITableView
der Kampf um die dynamische Dimensionierung IMHO gewonnen.
Vorsichtsmaßnahmen
Beachten Sie sehr, dass bei Verwendung von Prototypzellen zur Berechnung der geschätzten Artikelgröße dies unterbrochen wird, wenn Ihre XIB Größenklassen verwendet . Der Grund dafür ist, dass beim Laden Ihrer Zelle von einem XIB die Größenklasse mit konfiguriert wird Undefined
. Dies wird nur unter iOS 8 und höher unterbrochen, da unter iOS 7 die Größenklasse basierend auf dem Gerät geladen wird (iPad = Regular-Any, iPhone = Compact-Any). Sie können entweder die geschätzte Größe festlegen, ohne die XIB zu laden, oder Sie können die Zelle aus der XIB laden, sie zur collectionView hinzufügen (dies legt die traitCollection fest), das Layout ausführen und sie dann aus der Übersicht entfernen. Alternativ können Sie auch festlegen, dass Ihre Zelle den traitCollection
Getter überschreibt und die entsprechenden Merkmale zurückgibt. Es liegt an dir.
Lassen Sie mich wissen, wenn ich etwas verpasst habe, hoffe ich habe geholfen und viel Glück beim Codieren