2013-07-16 26 views
5

Lasst uns sagen, dass ichMit dequeueReusableCellWithIdentifier für individuelle Zellen

- (UITableViewCell*)tableView:(UITableView*) cellForRowAtIndexPath:(NSIndexPath*)indexPath 
{ 
    static NSString *cellID = @"Cell Identifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 

    if (!cell) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 
    else 
    { 
     return cell; 
    } 

    UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 15, box.size.width, 19.0f)]; 
    nameLabel.text = name; 
    [nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]]; 
    [nameLabel setFont: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 18.0f]]; 
    [nameLabel setBackgroundColor: [UIColor clearColor]]; 
    nameLabel.textAlignment = NSTextAlignmentCenter; 
    [cell addSubview: nameLabel]; 
} 

haben Was ist zu tun, dass zu gehen?

Wenn Zelle ist nicht Null, und sagen wir, Sie sind in Zeile 5, wird es die Zelle für Zeile 5 mit den genauen Textbeschriftungen usw. zurückgeben?

Grundsätzlich ist meine Frage, wenn Sie benutzerdefinierte Zellen mit Etiketten, Bildansichten usw. haben. Wie verwenden Sie cellForRowAtIndexPath mit dequeueReusableCellWithIdentifier?

+0

ist es für Tableviewcell gleich, ob es Gewohnheit ist oder nicht. Sie erhalten das Zellenobjekt und setzen alle seine Zustände zurück und fügen dann Ihren Inhalt hinzu. Also, ja, Sie müssen den Inhalt in den Etiketten/Bildern aufräumen (indem Sie ihn auf Null setzen) und neuen Inhalt bereitstellen. – rydgaze

+1

In diesem Code gibt es keine Möglichkeit, auf das UILabel-Objekt zuzugreifen, außer durch das Aufzählen von Teilansichten der Zelle, die ziemlich hässlich ist. Besser, eine Unterklasse von UITableViewCell zu verwenden, die eine UILabel -Eigenschaft hat, so dass sie leicht zugänglich ist. –

Antwort

0

Ja, wenn Sie eine Zelle aus der Warteschlange entfernen, der Sie diese Labels bereits hinzugefügt haben, werden sie und ihr Text immer noch so angezeigt, wie Sie sie beim Erstellen dieser bestimmten Zelle hinterlassen haben.

Erstellen Sie eine UITableViewCell-Unterklasse, nennen wir sie MyTableViewCell mit Eigenschaften, die die benötigten labels/imageViews/etc enthalten. Sobald Sie eine Ihrer MyTableViewCell entweder aus der Warteschlange genommen oder zugewiesen haben, können Sie den Text/images/etc für diese Eigenschaften festlegen. Wie folgt aus:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"identifier"; 

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
     cell = [[MyTableViewCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:CellIdentifier]; 
    } 



    cell.nameLabel.text = name; 
    cell.imageView.image = anImage; 


    return cell; 
} 

Ein großes Problem mit Ihrer Methode ist die conditionals Warteschlangenauflösungs-Umgebung und zu schaffen. In Ihrer Methode richten Sie die Zelle nur dann mit dem Label ein, wenn sie initialisiert wurde (Sie geben sofort eine Zelle aus der Warteschlange zurück, ohne sie zu formatieren). Sie möchten jedoch, dass diese Einstellung sowohl für in Warteschleifen als auch manuell instanziierte Zellen erfolgt. Beachten Sie, wie dies in meiner Methode passiert, die Return-Anweisung befindet sich ganz unten. Dadurch wird sichergestellt, dass sowohl erstellte als auch wiederverwendete Zellen über die entsprechenden Daten verfügen.

EDIT: Eine wichtige Sache, die ich weggelassen habe, werden Sie die Eigenschaften Ihrer Zelle in seiner initWithStyle: reuseIdentifier: Methode instanziieren und sie als Unteransichten der Zelle hinzufügen. Dies ist der Fall, wenn Sie den Text des Labels (oder was auch immer) in Ihrer cellForRowAtIndexPath-Methode festlegen, wurde er bereits erstellt. Grundsätzlich verwaltet die Zelle ihre eigenen Ansichten und der UITableView-Delegat muss sich nur darum kümmern, diese Ansichten mit Daten zu füllen.

3

Sie versuchen, eine Zelle aus der Warteschlange zu entfernen. Wenn der Versuch fehlgeschlagen ist (Zelle ist null), erstellen Sie eine Zelle und konfigurieren sie ihre Ansichten (nicht die Daten in der Ansicht). Anschließend füllen Sie die Ansichten mit Daten oder Einstellungen, die Zelle zu Zelle ändern. Außerdem sollten Sie der Zelle contentView keine benutzerdefinierten Ansichten hinzufügen, nicht die Zelle selbst.

#define NAME_LABEL_TAG 1234 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *cellID = @"Cell Identifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 15, box.size.width, 19.0f)]; 
     nameLabel.tag = NAME_LABEL_TAG; 
     [nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]]; 
     [nameLabel setFont: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 18.0f]]; 
     [nameLabel setBackgroundColor: [UIColor clearColor]]; 
     nameLabel.textAlignment = NSTextAlignmentCenter; 
     [cell.contentView addSubview: nameLabel]; 
    } 

    // Populate views with data and retrieve data for "name" variable 
    UILabel *nameLabel = (UILabel *)[cell.contentView viewWithTag:NAME_LABEL_TAG]; 
    nameLabel.text = name; 

    // Return fully configured and populated cell 
    return cell; 
} 

Wenn Sie eine komplexe Zelle haben, ist es oft einfacher ist es im Interface Builder und Unterklasse UITableViewCell zu erstellen, damit Sie benutzerdefinierte Eigenschaften haben können, die auf Ihre Labels, Buttons beziehen usw.

+10

Sie sollten wissen, dass wenn Sie Ihre Zelle in das Storyboard machen, dequeueReusableCellWithIdentifier: garantiert eine Zelle zurückgibt, also Ihre if (! Cell) -Klausel niemals laufen. – rdelmar

+0

können Sie nameLabel.text = name aufrufen; obwohl nameLabel nicht referenziert wurde, wenn die Zelle nicht null ist. –

+0

nameLabel wird außerhalb des Geltungsbereiches der 'if (! Cell)' liegen. Sie sollten viewWithTag verwenden, um die Bezeichnung abzurufen. –

0

UITableView zuerst fragen Sie für die Anzahl der erwarteten Zellen. Dann ist es load through - tableView: cellForRowAtIndexPath: Methode Zellen, die angezeigt wird + etwas zum reibungslosen Scrollen, mehr Objekte, die es nicht erstellt. Erstellte Objekte (nach Benutzer) in der Tabellenansicht gespeichert und Sie können nicht durch dequeueReusableCellWithIdentifier zugreifen: Methode. TableView fragt den Benutzer nach dem Ändern der aktuell erstellten Zellen beim Scrollen. Wenn hier ein freies Objekt ist - nimm es aus dequeueReusableCellWithIdentifier: ein anderes - erstelle ein neues.

0

Um nicht jede einzelne Tabellenzelle zuordnen zu müssen, weist eine Tabelle nur zu, was benötigt wird. Wenn nur 8 Zellen auf eine Seite passen, dann werden in einer Tabellenansicht nur 8 Zellen oder 9 Zellen zugeordnet. Ich erinnere mich nicht, ob es eine Auffüllung hat. Wenn Sie in einer Tabellenansicht blättern und die Zelle die Seite verlässt, wird die Zelle in die Warteschlange gestellt, um sie erneut zu verwenden. Anstatt eine neue Zelle neu zuzuweisen, wird in der Tabellenansicht eine vorhandene Zelle verwendet.Wenn Sie Ihre Zellen erstellen/zuweisen, geben Sie ihr eine Kennung, diese Kennung wird verwendet, um eine Zelle abzurufen, die mit dieser Zeichenfolge markiert ist.

0

können Sie entweder diese

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath 

Dieses nach iOS 6

Oder Sie können auch Ihre Klasse irgendwo in ViewDidLoad registrieren und verwenden ResuseIdentifier, so dass Sie die ResuseIdentifier nicht schreiben müssen Teil in cellForRowAtIndexPath

- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0) 

Hope this Sie hilft ...