Autolayout ignoriert mehrzeilige detailTextLabel bei der Berechnung von UITableViewCell height (alle Stile)

8

Ich versuche also, die eingebauten UITableViewCell Styles - speziell UITableViewCellStyleSubtitle - mit einer (einzelnen) Zeile textLabel , aber multiline detailTextLabel . Aber die (automatisch) berechnete Zellenhöhe ist konsistent zu kurz und scheint zu ignorieren, dass es mehr als eine Linie von Details gibt.

Ich habe versucht mit numberOfLines = 0, geschätztRowHeight, UITableViewAutomaticDimension, preferredMaxWidthLayout, etc., aber in allen Permutationen das Verhalten - in der Tat für alle die UITableViewCell Stile - erscheint die UITableViewAutomaticDimension Zellhöhenberechnung wird ein mehrzeiliges textLabel (yay!) korrekt berücksichtigen, nimmt aber fälschlicherweise an, dass das detailTextlabel höchstens eine einzige Zeile (nay!) ist. Folglich sind Zellen mit einem mehrzeiligen detailTextLabel zu kurz, und daher ist der Zellinhalt über die Ober- und Unterseite der Zelle hinaus ausgelaufen.

Ich habe eine schnelle Test-App veröffentlicht, die dieses Verhalten auf GitHub hier anzeigt. Das Hinzufügen zusätzlicher Textzeilen ist in Ordnung - alle Zellenstile erhöhen sich entsprechend in der Höhe -, aber das Hinzufügen zusätzlicher Detailzeilen ändert nichts an der Zellenhöhe und führt schnell zum Überlaufen des Inhalts; Der Text und das Detail sind selbst korrekt angeordnet und zusammen über der Mitte der Zelle korrekt zentriert (in diesem Sinn funktioniert layoutSubviews korrekt), aber die Gesamthöhe der Zelle selbst ist unverändert.

Es scheint fast so, als gäbe es kein Top & Amp; bottom constraints zwischen dem cell.contentView und den Labels, und stattdessen wird die Zellenhöhe direkt aus der Höhe der (möglicherweise mehrzeiligen) TextLabel und (nur einzeiligen) detailTextLabel berechnet, und dann wird alles über der Mitte von zentriert die Zelle ... Auch hier ist mehrzeiliges TextLabel in Ordnung, und ich mache nichts anderes zwischen den textLabel und detailTextLabel, aber nur das erstere (richtig) passt die Zellenhöhe an.

Meine Frage ist also, ob es möglich ist, die eingebauten UITableViewCell-Stile zu verwenden, um mehrzeilige detailTextLabels zuverlässig anzuzeigen, oder ist das einfach nicht möglich und müssen Sie stattdessen eine benutzerdefinierte Unterklasse erstellen? [oder fast äquivalent, ohne layoutSubviews in einer Unterklasse zu überschreiben und alle Beschränkungen manuell neu zu verkabeln].

[4. Mai 2016] Fazit: ab iOS9 mehrzeilige detailTextLabels funktionieren nicht wie erwartet mit UITableViewAutomaticDimension; Die Zelle wird konsistent zu kurz sein und der Text / das Detail wird über und unter den Text übertragen. Entweder müssen Sie manuell die korrekte Zellenhöhe selbst berechnen oder Sie erstellen und erstellen Ihre eigene äquivalente benutzerdefinierte UITableViewCell-Unterklasse oder (siehe meine Antwort unten) Unterklasse UITableViewCell und fix systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority: , um die korrekte Höhe [empfohlen]

zurückzugeben     
tiritea 13.04.2016, 01:50
quelle

5 Antworten

18

Weitere Untersuchungen (siehe UITableViewCellTest ) zeigen an, dass wenn UITableViewAutomaticDimension aktiviert ist, das System -systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority: aufruft. um die Zellenhöhe zu berechnen, und das ignoriert ziemlich genau die Höhe von detailTextLabel in seiner Berechnung (bug!?). Als Ergebnis wird für UITableViewCellStyleSubtitle die Zellenhöhe immer zu kurz sein [ein einzeiliges detailTextLabel kann nicht ganz über die Zelle hinausgehen, aber das liegt nur an der vorhandene obere und untere Ränder], und für UITableViewCellStyleValue1 oder UITableViewCellStyleValue2 ist die Höhe zu klein, wenn das detailTextLabel größer ist (z. B. mehr Zeilen) das textLabel . Das ist alles ein Problem für UITableViewCellStyleDefault , das keine detailTextLabel hat.

Meine Lösung war Unterklasse und Fix mit:

%Vor%

Und in der Ansicht Controller:

%Vor%

Sie können die vollständige Unterklasse von hier aus aufrufen: MultilineTableViewCell

Bis jetzt scheint dieser Fix gut zu funktionieren und hat mir die eingebauten UITableViewCellStyles mit mehrzeiligem Text und Details in Zellen mit selbstanpassender Größe und dynamischer Unterstützung ermöglicht. Dies vermeidet das Problem (und die Unordnung), die gewünschten Zellenhöhen in tableView:heightForRowAtIndexPath: manuell zu berechnen oder benutzerdefinierte Zellenlayouts zu erstellen.

[FEST IN iOS11]

Apple endlich hat diesen Fehler in iOS11 behoben. Ich habe meine Lösung so aktualisiert, dass sie nur die notwendige Korrektur auf Pre-11-Geräte anwendet (andernfalls enden Sie mit extra Leerzeichen oben und unten in Ihrer Zelle!).

    
tiritea 04.05.2016, 01:17
quelle
3

@tiriteas Antwort in Swift 3 (Danke nochmal!: D)

%Vor%     
Hlung 21.10.2016 03:40
quelle
1

Aus meiner Erfahrung unterstützen die eingebauten Zellen die automatische Größenanpassung mit Einschränkungen nicht. Ich denke, die beste Lösung besteht darin, eine benutzerdefinierte Zelle zu erstellen, es dauert ein paar Minuten und Sie müssen layoutSubview nicht überschreiben, das ist es wirklich einfach. Ändern Sie einfach den Typ der Zelle in der IB in benutzerdefiniert, ziehen Sie eine Beschriftung, legen Sie Einschränkungen fest (in der IB), legen Sie die Anzahl der Zeilen fest, erstellen Sie eine Unterklasse, ändern Sie die Zellenklasse in der IB in Ihre Unterklasse, erstellen Sie eine Steckdose in der Unterklasse und das ist die meiste Arbeit, Ich bin sicher, es gibt viele Tutorials im Netz, denen Sie folgen können.

    
Oleg Sherman 13.04.2016 04:16
quelle
1

Sieht so aus, als hätte Apple diesen Fehler in iOS 11 behoben.

    
Puneet Sharma 28.08.2017 09:52
quelle
1

Schnell 3

Nachdem ich verschiedene Antworten gelesen habe, habe ich die folgende Methode verwendet, um das Textattribut "UITableViewAutomaticDimension" zu erhalten. Verwenden Sie die einfache Stilzelle nur mit der Titelbezeichnung und verwenden Sie die attributierte Zeichenfolge für die Text- und Detailtextansicht. Vergessen Sie nicht, den Tabellenansichtszellenstil von Subtitle in Basic zu ändern.

%Vor%

Wie man in cellforrowatindexpath

verwendet %Vor%

Fügen Sie folgende Zeilen in viewdidload hinzu

%Vor%     
Vinay Krishna Gupta 30.08.2017 11:15
quelle

Tags und Links