Die Frage ist einfach: Wie lädt man benutzerdefinierte UITableViewCell
aus Xib-Dateien? Auf diese Weise können Sie Interface Builder zum Entwerfen Ihrer Zellen verwenden. Die Antwort ist anscheinend aufgrund von Speicherverwaltungsproblemen nicht einfach. Dieser Thread erwähnt das Problem und schlägt eine Lösung vor, ist jedoch vor der NDA-Veröffentlichung und enthält keinen Code. Hier ist ein langer Thread , der das Problem behandelt, ohne eine endgültige Antwort zu geben.
Hier ist ein Code, den ich verwendet habe:
static NSString *CellIdentifier = @"MyCellIdentifier";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCell *)[nib objectAtIndex:0];
}
Um diesen Code zu verwenden, erstellen Sie MyCell.m / .h, eine neue Unterklasse von UITableViewCell
und fügen Sie sie IBOutlets
für die gewünschten Komponenten hinzu. Erstellen Sie dann eine neue "Leere XIB" -Datei. Öffnen Sie die Xib-Datei in IB, fügen Sie ein UITableViewCell
Objekt hinzu, setzen Sie den Bezeichner auf "MyCellIdentifier", setzen Sie die Klasse auf MyCell und fügen Sie Ihre Komponenten hinzu. Schließen Sie zum Schluss die IBOutlets
an die Komponenten an. Beachten Sie, dass wir den Eigentümer der Datei nicht in IB festgelegt haben.
Andere Methoden empfehlen, den Eigentümer der Datei festzulegen und vor Speicherverlusten zu warnen, wenn die Xib nicht über eine zusätzliche Factory-Klasse geladen wird. Ich habe das Obige unter Instrumente / Lecks getestet und keine Speicherlecks festgestellt.
Wie kann man also kanonisch Zellen aus Xibs laden? Stellen wir den Eigentümer der Datei ein? Brauchen wir eine Fabrik? Wenn ja, wie sieht der Code für die Fabrik aus? Wenn es mehrere Lösungen gibt, lassen Sie uns die Vor- und Nachteile der einzelnen Lösungen klären ...
quelle
Antworten:
Hier sind zwei Methoden, die der ursprüngliche Autor von einem IB-Ingenieur empfohlen hat .
Weitere Informationen finden Sie im aktuellen Beitrag. Ich bevorzuge Methode 2, da es einfacher erscheint.
Methode 1:
Methode 2:
Update (2014): Methode 2 ist noch gültig, es gibt jedoch keine Dokumentation mehr dafür. Früher war es in den offiziellen Dokumenten enthalten , jetzt wird es zugunsten von Storyboards entfernt.
Ich habe ein Arbeitsbeispiel auf Github veröffentlicht:
https://github.com/bentford/NibTableCellExample
Bearbeiten für Swift 4.2
quelle
Die richtige Lösung ist folgende:
quelle
Registrieren
Nach iOS 7 wurde dieser Prozess auf ( swift 3.0 ) vereinfacht :
Dequeue
Und später mit ( Swift 3.0 ) aus der Warteschlange entfernt :
Der Unterschied besteht darin, dass diese neue Methode nicht nur die Zelle aus der Warteschlange entfernt, sondern auch erstellt, wenn sie nicht vorhanden ist (das bedeutet, dass Sie keine
if (cell == nil)
Spielereien durchführen müssen), und dass die Zelle wie im obigen Beispiel einsatzbereit ist.Und natürlich ist der Typ der zugeordneten Klasse der Zelle derjenige, den Sie in der .xib-Datei für die
UITableViewCell
Unterklasse definiert haben, oder alternativ mit der anderen Registermethode.Aufbau
Im Idealfall wurden Ihre Zellen bereits zum Zeitpunkt der Registrierung und der
cellForRowAtIndexPath
Methode, mit der Sie sie einfach ausfüllen, hinsichtlich Aussehen und Position des Inhalts (wie Beschriftungen und Bildansichten) konfiguriert .Alle zusammen
Und natürlich ist dies alles in ObjC mit den gleichen Namen verfügbar.
quelle
[self.tableView registerNib:[UINib nibWithNibName:@"BlaBlaTableViewCell" bundle:nil] forCellReuseIdentifier:kCellIdentifier];
Nahm Shawn Cravers Antwort und räumte sie ein bisschen auf.
BBCell.h:
BBCell.m:
Ich mache alle meine UITableViewCell-Unterklassen von BBCell und ersetze dann den Standard
mit:
quelle
Ich habe Bentfords Methode 2 verwendet :
Es funktioniert, aber achten Sie in Ihrer benutzerdefinierten UITableViewCell .xib-Datei auf Verbindungen zum Eigentümer der Datei.
Indem Sie
owner:self
IhreloadNibNamed
Erklärung abgeben, legen Sie denUITableViewController
Eigentümer Ihrer Datei festUITableViewCell
.Wenn Sie in IB in die Header-Datei ziehen und dort ablegen, um Aktionen und Outlets einzurichten, werden diese standardmäßig als Eigentümer der Datei eingerichtet.
In
loadNibNamed:owner:options
versucht der Apple-Code, Eigenschaften für Ihr Gerät festzulegenUITableViewController
, da dies der Eigentümer ist. Da diese Eigenschaften dort jedoch nicht definiert sind, wird die Fehlermeldung angezeigt, dass sie mit der Codierung von Schlüsselwerten kompatibel sind :Wenn stattdessen ein Ereignis ausgelöst wird, erhalten Sie eine NSInvalidArgumentException:
Eine einfache Problemumgehung besteht darin, Ihre Interface Builder-Verbindungen
UITableViewCell
anstelle des Dateibesitzers auf Folgendes zu verweisen :quelle
Ich habe mich entschieden zu posten, da mir keine dieser Antworten gefällt - die Dinge können immer einfacher sein, und dies ist bei weitem der prägnanteste Weg, den ich gefunden habe.
1. Erstellen Sie Ihre Xib in Interface Builder nach Ihren Wünschen
2. In Ihrer UIViewController- oder UITableViewController-Unterklasse
3. In Ihrer MyTableViewCellSubclass
quelle
Wenn Sie Interface Builder zum Erstellen von Zellen verwenden, überprüfen Sie, ob Sie die Kennung im Inspektor festgelegt haben. Überprüfen Sie dann, ob es beim Aufrufen von dequeueReusableCellWithIdentifier identisch ist.
Ich habe versehentlich vergessen, einige Bezeichner in einem tabellenlastigen Projekt festzulegen, und die Leistungsänderung war wie Tag und Nacht.
quelle
Das Laden von UITableViewCells aus XIBs spart viel Code, führt jedoch normalerweise zu einer schrecklichen Bildlaufgeschwindigkeit (tatsächlich ist es nicht die XIB, sondern die übermäßige Verwendung von UIViews, die dies verursacht).
Ich schlage vor, Sie werfen einen Blick darauf: Link-Referenz
quelle
Hier ist die Klassenmethode, mit der ich benutzerdefinierte Zellen aus XIBs erstellt habe:
Dann habe ich in der XIB den Klassennamen festgelegt und die Kennung wiederverwendet. Danach kann ich diese Methode einfach in meinem View Controller anstelle von aufrufen
Es ist schnell genug und wird in zwei meiner Versandanwendungen verwendet. Es ist zuverlässiger als das Anrufen
[nib objectAtIndex:0]
und meiner Meinung nach zumindest zuverlässiger als das Beispiel von Stephan Burlot, da Sie garantiert nur einen Blick aus einem XIB werfen können, der der richtige Typ ist.quelle
Die richtige Lösung ist dies
quelle
Das Nachladen der NIB ist teuer. Laden Sie es besser einmal und instanziieren Sie die Objekte, wenn Sie eine Zelle benötigen. Beachten Sie, dass Sie mit dieser Methode UIImageViews usw. zur Feder hinzufügen können, auch mehrere Zellen (Apples "registerNIB" iOS5 erlaubt nur ein Objekt der obersten Ebene - Fehler 10580062 "iOS5 tableView registerNib: übermäßig restriktiv"
Mein Code ist also unten - Sie lesen die NIB einmal ein (beim Initialisieren wie ich oder in viewDidload - was auch immer. Von da an instanziieren Sie die Feder in Objekte und wählen dann die gewünschte aus. Dies ist viel effizienter als das Laden der Feder über und über.
quelle
Überprüfen Sie dies - http://eppz.eu/blog/custom-uitableview-cell/ - wirklich bequem, indem Sie eine winzige Klasse verwenden, die eine Zeile in der Controller-Implementierung endet:
quelle
Der richtige Weg, dies zu tun, besteht darin, eine UITableViewCell-Unterklassenimplementierung, einen Header und XIB zu erstellen. Entfernen Sie in der XIB alle Ansichten und fügen Sie einfach eine Tabellenzelle hinzu. Legen Sie die Klasse als Namen der UITableViewCell-Unterklasse fest. Machen Sie den Dateieigentümer zum Klassennamen der UITableViewController-Unterklasse. Verbinden Sie den Dateieigentümer über den tableViewCell-Ausgang mit der Zelle.
In der Header-Datei:
In der Implementierungsdatei:
quelle
Was ich dafür tue, ist eine
IBOutlet UITableViewCell *cell
in Ihrer Controller-Klasse zu deklarieren . Rufen Sie dann dieNSBundle loadNibNamed
Klassenmethode auf, die dieUITableViewCell
der oben deklarierten Zelle zuführt.Für die xib werde ich eine leere xib erstellen und das
UITableViewCell
Objekt in IB hinzufügen, wo es nach Bedarf eingerichtet werden kann. Diese Ansicht wird dann mit der ZelleIBOutlet
in der Controller-Klasse verbunden.NSBundle-Ergänzungen loadNibNamed (ADC-Login)
cocoawithlove.com Artikel, aus dem ich das Konzept bezogen habe (Beispiel-App für Telefonnummern herunterladen)
quelle
Erstellen Sie Ihre eigene angepasste Klassenunterklasse
AbcViewCell
ausUITableViewCell
(Stellen Sie sicher, dass der Name Ihrer Klassendatei und der Name der NIB-Datei identisch sind.)Erstellen Sie diese Erweiterungsklassenmethode.
Benutze es.
let cell: AbcViewCell = UITableViewCell.fromNib()
quelle
Importieren Sie zuerst Ihre benutzerdefinierte Zellendatei
#import "CustomCell.h"
und ändern Sie dann die Delegatenmethode wie folgt:quelle
In Swift 4.2 und Xcode 10
Ich habe drei XIB-Zellendateien
Registrieren Sie in ViewDidLoad Ihre XIB-Dateien wie folgt ...
Dies ist der erste Ansatz
Zweiter Ansatz Registrieren Sie XIB-Dateien direkt in cellForRowAt indexPath:
Dies sind meine Tableview-Delegatenfunktionen
quelle
Hier ist meine Methode dafür: Laden von benutzerdefinierten UITableViewCells aus XIB-Dateien… Noch eine andere Methode
Die Idee ist, eine SampleCell-Unterklasse von
UITableViewCell
mit einerIBOutlet UIView *content
Eigenschaft und einer Eigenschaft für jede benutzerdefinierte Unteransicht zu erstellen, die Sie aus dem Code konfigurieren müssen. Dann erstellen Sie eine SampleCell.xib-Datei. Ändern Sie in dieser NIB-Datei den Dateieigentümer in SampleCell. Fügen Sie einen Inhalt hinzu, dessenUIView
Größe Ihren Anforderungen entspricht. Fügen Sie alle gewünschten Unteransichten (Beschriftung, Bildansichten, Schaltflächen usw.) hinzu und konfigurieren Sie sie. Verknüpfen Sie abschließend die Inhaltsansicht und die Unteransichten mit dem Dateieigentümer.quelle
Hier ist ein universeller Ansatz zum Registrieren von Zellen in
UITableView
:Erläuterung:
Reusable
Das Protokoll generiert eine Zellen-ID aus seinem Klassennamen. Stellen Sie sicher, dass Sie die Konvention befolgen :cell ID == class name == nib name
.UITableViewCell
entspricht demReusable
Protokoll.UITableView
Die Erweiterung abstrahiert den Unterschied bei der Registrierung von Zellen über Feder oder Klasse.Anwendungsbeispiel:
quelle
Ich weiß nicht, ob es einen kanonischen Weg gibt, aber hier ist meine Methode:
Und benutze diesen Code:
In Ihrem Beispiel mit
kann brechen, wenn Apple die Reihenfolge der Elemente in der xib ändert.
quelle
quelle
Diese Erweiterung erfordert Xcode7 Beta6
Erstellen Sie eine Xib-Datei, die nur 1 benutzerdefinierte UITableViewCell enthält.
Lade es.
quelle
quelle