Die beste Methode zur Berechnung der UITableViewCell-Höhe ohne contentView-Rahmen

9

ZUSAMMENFASSUNG

Da wir nicht immer wissen, was der Rahmen einer Zelle oder deren Inhaltsansicht sein wird (aufgrund von Bearbeitungen, Drehungen, Zubehöransichten usw.), ist der beste Weg, die Höhe zu berechnen in tableView:heightForRowAtIndexPath: , wenn die Zelle ein Textfeld oder eine Beschriftung mit variabler Höhe enthält?

Einer meiner UITableViewController's enthält die folgende Präsentation: UITableViewCell mit UITextView.

UITextView sollte die gleiche Breite und Höhe wie UITableViewCell haben.

Ich habe die UITableViewCell-Unterklasse erstellt und dann initialisiert und mit UITextView initialisiert (UITextView ist ein privates Feld von meinem UITableViewController)

%Vor%

Ich habe die folgende Methode in meiner UITableViewCell-Unterklasse implementiert:

%Vor%

und natürlich habe ich die folgende UITableViewDataSource Methode implementiert (schau! Ich benutze self.view.frame.size.width (aber ich brauche wirklich UITableViewCell contentView Rahmenbreite):

%Vor%

Ich habe auch die folgende Methode implementiert (das ist nicht so wichtig, aber krank poste es trotzdem, nur um zu erklären, dass die Höhe der Zelle dynamisch ist, wird sie nach dem Ändern von Text in UITextView schrumpfen oder expandieren)

%Vor%

Und jetzt ist meine Frage: Nach dem Laden der Ansicht ruft UITableViewController die Methoden in der folgenden Reihenfolge auf: (like einige entfernen, wie titleForHeaderInSection und etc zur Vereinfachung)

%Vor%

und nur dann

%Vor%

Schau! Ich sollte die korrekte UITableViewCell Höhe vor CellForRowAtIndexPath zurückgeben! Das heißt: Ich kenne UITableViewCell contentView frame nicht. Und ich kann es nicht programmgesteuert bekommen.

Diese Breite kann eine der folgenden sein:

  1. iPhone einfache Tabelle, Hochformat
  2. iPhone einfache Tabelle, Querformat
  3. iPhone gruppierte Tabelle, Hochformat
  4. iPhone gruppierte Tabelle, Querformat
  5. und das gleiche für das iPad (weitere 4 Werte)

Und vergessen Sie nicht, dass der contentView-Rahmen aufgrund von UITableViewCell accessoryType oder wegen des Bearbeitungsstatus von UITableView kleiner sein kann. (Zum Beispiel, wenn wir UITableViewCell mit mehrzeiligen UIL-Zeichen beliebiger Höhe in einem beliebigen Bearbeitungszustand und mit einem AccessoryView haben)

Also ist dieses Problem von grundlegender Bedeutung: Ich kann den Zellinhalt nur nicht anzeigen, um die Rahmenbreite zu beschränken, weil ich diese Höhe vor dem Zelllayout contentView zurückgeben soll. (Und das ist übrigens ziemlich logisch) Aber dieser ContentView-Frame ist wirklich wichtig.

Natürlich kann ich diese Breite manchmal genau kennen und "hardcodieren" (Beispiel: UITableViewCellAccessoryDisclosureIndicator hat eine Breite von 20 px, und tableView kann nicht im Bearbeitungszustand sein, dann kann ich self.view.frame.size.width - 20 schreiben und die Aufgabe ist erledigt)! Oder manchmal ist contentView gleich dem View-Frame von UITableViewController!

Manchmal benutze ich self.view.frame.width in -tableView: heightForRowAtIndexPath: method .. (wie jetzt, und es funktioniert ziemlich gut, aber nicht perfekt wegen der gruppierten UITableView, sollte einige konstante Werte subtrahieren, und sie sind für 2 Geräte * 2 Orientierungen unterschiedlich)

Manchmal habe ich einige #definierte Konstanten in UITableViewCell (wenn ich die Breite genau kenne) ...

Manchmal benutze ich eine Dummy-Vorbelegung von UITableViewCell (was nur dumm ist, aber manchmal ist es ziemlich elegant und einfach zu benutzen) ...

Aber ich mag nichts davon.

Was ist die beste Entscheidung? Vielleicht sollte ich eine Hilfsklasse erstellen, die mit solchen Parametern initialisiert wird: Zubehöransichten, Geräteausrichtung, Gerätetyp, Tabellenansichtsstatus, Tabellenansichtsstil (einfach, gruppiert), Controller - Ansichtsrahmen und einige andere, die einige Konstanten (wie gruppierte tableView - Versetzung, usw.) enthalten und sie zum Suchen des erwartet UITableViewCell contentAnsicht Breite? ;)

Danke

    
Valentyn Kuznietsov 19.06.2012, 14:33
quelle

2 Antworten

1

Die Tabellenansicht verwendet die Methode tableView:heightForRowAtIndexPath: , um ihre contentSize vor dem Erstellen von UITableViewCell -Zellen zu bestimmen. Wenn Sie aufhören und darüber nachdenken, ist dies sinnvoll, da das erste, was Sie mit UIScrollView machen würden, seine contentSize ist. Ich habe schon früher ein ähnliches Problem kennengelernt, und ich habe herausgefunden, dass es am besten ist, eine Hilfsfunktion zu haben, die den Inhalt in die UITableViewCell bringen und die Höhe dieses UITableViewCell vorhersagen kann. Also denke ich, dass Sie eine Art von Datenstruktur erstellen möchten, die den Text in jedem UITableViewCell speichert, ein NSDictionary mit NSIndexPaths als Schlüssel und der Text als Werte würden gut funktionieren. Auf diese Weise können Sie die Höhe des benötigten Texts finden, ohne auf UITableViewCell zu verweisen.

    
Sean Lynch 20.06.2012 09:45
quelle
1

Obwohl Sie Höhen für Beschriftungen, die in Tabellenansichtszellen enthalten sind, wirklich dynamisch in '- layoutSubviews' einer UITableViewCell-Unterklasse berechnen können, gibt es keine ähnliche Möglichkeit (wie ich weiß) für Zellenhöhen in '- tableView: heightForRowAtIndexPath: 'eines Delegates für die Tabellenansicht.

Bedenken Sie Folgendes:

%Vor%

Leider wird aber zu der Zeit '- tableView: heightForRowAtIndexPath:' aufgerufen, das ist zu früh, weil cell.textLabel.frame noch auf CGRectZero = {{0, 0}, {0, 0}} gesetzt ist.

AFAIK wird das weder mit dem Rahmen der Inhaltsansicht noch mit der Zusammenfassung einzelner Rahmen der einzelnen Bilder möglich sein ...

Der einzige Weg, an den ich denken kann, ist eine Convenience-Klasse, Methoden, Konstanten oder ähnliches, die versuchen, alle möglichen Breiten in jeder Geräteausrichtung auf jedem Gerät zu verbergen:

%Vor%

Beachten Sie auch, dass wir seit kurzem auch das neue iPhone 5 mit einer Breite von 4 Zoll (568 statt 480) im Querformat verwenden.

Diese ganze Sache ist ziemlich beunruhigend, ich weiß ... Prost.

    
Ali 18.09.2012 07:43
quelle