2013-07-16 21 views
5

Diciamo che hoUtilizzando dequeueReusableCellWithIdentifier per le cellule personalizzati

- (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]; 
} 

Cos'è che sta per fare?

Se la cella non è nulla, e diciamo che sei alla riga 5, restituirà la cella per la riga 5 con le etichette di testo esatte, ecc.?

Fondamentalmente, la mia domanda è, se si dispone di celle personalizzate con etichette, immagini, ecc. Come si usa cellForRowAtIndexPath con dequeueReusableCellWithIdentifier?

+0

è lo stesso per tableviewcell se è personalizzato o no. Si ottiene l'oggetto cella e si ripristinano tutti i suoi stati e quindi si aggiunge il contenuto. Quindi sì, dovrai pulire i contenuti nelle etichette/immagini (impostandolo su zero) e fornire nuovi contenuti. – rydgaze

+1

In questo codice, non è possibile accedere nuovamente all'oggetto UILabel tranne che enumerando le sottoview della cella che è piuttosto brutta. Meglio usare una sottoclasse di UITableViewCell che ha una proprietà UILabel quindi è facilmente accessibile –

risposta

0

Sì, la rimozione di una cella a cui sono già state aggiunte le etichette avrà ancora loro e il loro testo proprio come lo hai lasciato quando hai creato quella cella specifica.

Creare una sottoclasse UITableViewCell, chiamiamola MyTableViewCell che ha proprietà che contengono le etichette/imageViews/etc di cui avrà bisogno. Una volta che hai dequalificato o assegnato all'inizio uno dei tuoi MyTableViewCell, puoi impostare il testo/le immagini/ecc su queste proprietà. Come questo:

- (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; 
} 

Un grosso problema con il vostro metodo è i condizionali circostanti dequeueing e la creazione. Nel metodo si imposta la cella sull'etichetta solo quando è allocata l'inizializzazione (si restituisce immediatamente una cella dequalificata senza formattarla). Tuttavia, si desidera che questa configurazione si verifichi sia per le celle dequalificate che per quelle istanziate manualmente. Notate come questo accade nel mio metodo, la dichiarazione di ritorno è in fondo. Ciò garantirà che sia le celle create che quelle riutilizzate abbiano i dati appropriati.

MODIFICA: una cosa importante che ho tralasciato, si istanziare le proprietà della cella nel suo metodo initWithStyle: reuseIdentifier: e aggiungerle come subviews alla cella. Questo è così quando si va ad impostare il testo dell'etichetta (o qualsiasi altra cosa) nel proprio metodo cellForRowAtIndexPath, è già stato creato. Fondamentalmente la cella gestisce la creazione delle proprie viste e il delegato di UITableView deve solo preoccuparsi di riempire quelle viste con i dati.

3

Si tenta di deselezionare una cella. Se il tentativo fallisce (cella è nullo), allora si crea una cella e la si configura come vista (non i dati all'interno della vista). Successivamente, si popolano le visualizzazioni con tutti i dati o le impostazioni che cambiano da cella a cella. Inoltre, è necessario aggiungere eventuali visualizzazioni personalizzate al numero di cella contentView, non alla cella stessa.

#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; 
} 

Se si dispone di una cella complesso, è spesso più facile per creare in Interface Builder e sottoclasse UITableViewCell così si può avere proprietà personalizzate che si riferiscono alle etichette, bottoni, ecc

+10

Dovresti essere consapevole che se crei la tua cella nello storyboard, dequeueReusableCellWithIdentifier: è garantito il ritorno di una cella, quindi la tua clausola if (! Cell) mai correre. – rdelmar

+0

puoi chiamare nameLabel.text = nome; anche se nameLabel non è stato referenziato per quando la cella non è nulla. –

+0

nameLabel non rientra nel campo "if (! Cell)". Dovresti usare viewWithTag per ottenere l'etichetta. –

0

UITableView in un primo momento chiedere per il numero di celle previste. Quindi viene eseguito il caricamento: tableView: cellForRowAtIndexPath: celle di metodo che verranno visualizzate + alcune per lo scorrimento uniforme, più oggetti che non crea. Oggetti creati (dall'utente) memorizzati nella vista tabella e accesso non utilizzato tramite dequeueReusableCellWithIdentifier: metodo. TableView chiede all'utente di modificare le celle attualmente create quando scorre. Se qui è un oggetto libero, prendilo da dequeueReusableCellWithIdentifier: un altro - creane uno nuovo.

0

per non dover allocare ogni singola cella di tabella, una tabella assegna solo ciò che è necessario. Se solo 8 celle si adattano a una pagina, una vista tabella assegna solo 8 celle o 9 non ricordo se ha un riempimento. Quando si scorre una vista tabella e la cella esce dalla pagina, la cella viene accodata per essere riutilizzata, invece di riassegnare una nuova cella la vista tabella prende una esistente questo processo è chiamato dequeue-ing.Quando si effettuano/assegnano le celle a cui viene assegnato un identificatore, questo identificatore viene utilizzato per recuperare una cella contrassegnata da tale stringa.

0

È possibile utilizzare questo

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

Questo è disponibile dopo iOS 6

Oppure si può anche registrare la classe da qualche parte in viewDidLoad e utilizzare ResuseIdentifier, quindi non c'è bisogno di scrivere il ResuseIdentifier parte in cellForRowAtIndexPath

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

Spero che questo ti aiuta ...