Come personalizzare il colore di sfondo di un UITableViewCell?


188

Vorrei personalizzare lo sfondo (e forse anche il bordo) di tutti gli UITableViewCells all'interno del mio UITableView. Finora non sono stato in grado di personalizzare queste cose, quindi ho un sacco di celle con sfondo bianco che è l'impostazione predefinita.

C'è un modo per farlo con l'SDK di iPhone?

Risposte:


193

Devi impostare il colore di sfondo del contenuto della cella Visualizza sul tuo colore. Se usi accessori (come frecce di rivelazione, ecc.), Verranno visualizzati in bianco, quindi potresti dover eseguire il roll delle versioni personalizzate di questi.


108
ad esempio myCell.contentView.backgroundColor = [UIColor greenColor];
JoBu1324,

1
La risposta di vlado.grigorov è più flessibile - vedi la risposta di William Denniss
JoBu1324

3
Qualche link su come procedere UITableViewCellAccessoryCheckmark, ad esempio? Grazie.
Dan Rosenstark,

6
Per vederlo a volte è necessario impostare:cell.textLabel.backgroundColor = [UIColor clearColor];
Evan Moran

205

Ecco il modo più efficiente in cui mi sono imbattuto per risolvere questo problema, utilizzare il metodo delegato willDisplayCell (questo si occupa del colore bianco per lo sfondo dell'etichetta di testo e quando si utilizza cell.textLabel.text e / o cell.detailTextLabel.text ):

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { ... }

Quando questo metodo delegato viene chiamato, il colore della cella viene controllato tramite la cella anziché dalla vista tabella, come quando si utilizza:

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

Quindi nel corpo del metodo del delegato di cella aggiungi il seguente codice per alternare i colori delle celle o usa semplicemente la chiamata di funzione per rendere tutte le celle della tabella dello stesso colore.

if (indexPath.row % 2)
{
    [cell setBackgroundColor:[UIColor colorWithRed:.8 green:.8 blue:1 alpha:1]];
}
else [cell setBackgroundColor:[UIColor clearColor]];

Questa soluzione ha funzionato bene nelle mie circostanze ...


Questa è una soluzione più pulita. La maggior parte delle altre soluzioni richiede la sottoclasse di UITableViewCell. La soluzione di vlado.grigorov non funziona per me.
Ronnie Liew,

In effetti, e questo è il metodo che Apple stesso raccomanda in base alle varie presentazioni del WWDC che ho visto.
Mike Weller,

Bello: TRANNE quando è necessario aggiungere nuove righe in cima all'elenco. Questo metodo rende tutte le aggiunte dello stesso colore. L'aggiornamento lo risolve, ma richiede tempo non necessario. Scoperto ieri ...
JOM

Questo sembra funzionare bene, tranne quando si utilizzano Core Data. Le nuove celle aggiunte tramite un NSFetchedResultsController non sembrano chiamare correttamente WillDisplayCell. Sono in perdita per farlo funzionare ...
Radven l'

La linea equivalente per impostare il colore di sfondo in Swift 2.0:cell.backgroundColor = UIColor.clearColor
kbpontius

104

Questo è davvero semplice, dal momento che OS 3.0 ha appena impostato il colore di sfondo della cella nel metodo willDisplayCell. Non è necessario impostare il colore in cellForRowAtIndexPath.

Questo funziona sia per lo stile semplice che per quello raggruppato:

Codice:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = [UIColor redColor];
}

PS: qui l'estratto della documentazione per willDisplayCell:

"Una vista tabella invia questo messaggio al suo delegato appena prima di utilizzare la cella per disegnare una riga, consentendo così al delegato di personalizzare l'oggetto cella prima che venga visualizzato. Questo metodo offre al delegato la possibilità di sovrascrivere le proprietà basate sullo stato impostate in precedenza da la vista tabella, come la selezione e il colore di sfondo. Dopo che il delegato ritorna, la vista tabella imposta solo le proprietà alfa e cornice, e quindi solo quando si animano le righe mentre si spostano dentro o fuori. "

Ho trovato queste informazioni in questo post da Colionel . Ringrazialo!


3
Questa dovrebbe essere contrassegnata come la risposta corretta in quanto non devi nemmeno avere nulla se hai una divulgazioneIndiator
Ashish Awaghad

1
Questo non funziona se vuoi un colore di sfondo della cella diverso dallo sfondo delle viste tabella per me.
Chris,

Per la cella di gruppo, puoi impostarla su cellForRow
Eayrs il

58

L'approccio migliore che ho trovato finora è impostare una vista di sfondo della cella e cancellare lo sfondo delle sottoview delle celle. Certo, questo sembra bello solo su tavoli con stile indicizzato, non importa con o senza accessori.

Ecco un esempio in cui lo sfondo della cella è giallo:

UIView* backgroundView = [ [ [ UIView alloc ] initWithFrame:CGRectZero ] autorelease ];
backgroundView.backgroundColor = [ UIColor yellowColor ];
cell.backgroundView = backgroundView;
for ( UIView* view in cell.contentView.subviews ) 
{
    view.backgroundColor = [ UIColor clearColor ];
}

1
In questo caso, assicurarsi di impostare anche la proprietà opaca su NO.
Lily Ballard

11
L'uso dei controlli trasparenti delle celle non è davvero raccomandato. Le prestazioni di scorrimento saranno influenzate molto, motivo per cui Apple dice sempre di utilizzare i controlli opachi.
Mike Weller,

3
Su iOS 4.2 e versioni successive sembra che il loop non sia più necessario.
Frank Schmitt,

Molto bella. Funziona perfettamente quando si utilizzano le viste degli accessori !!
RyanG

19

Mettilo semplicemente nel tuo file di classe delegato UITableView (.m):

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell  forRowAtIndexPath:(NSIndexPath *)indexPath 
{
    UIColor *color = ((indexPath.row % 2) == 0) ? [UIColor colorWithRed:255.0/255 green:255.0/255 blue:145.0/255 alpha:1] : [UIColor clearColor];
    cell.backgroundColor = color;
}

7

Concordo con Seba, ho provato a impostare il mio colore di riga alternato nel metodo delegato rowForIndexPath ma ottenevo risultati incoerenti tra 3.2 e 4.2. Quanto segue ha funzionato benissimo per me.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    if ((indexPath.row % 2) == 1) {
        cell.backgroundColor = UIColorFromRGB(0xEDEDED);
        cell.textLabel.backgroundColor = UIColorFromRGB(0xEDEDED);
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }
    else
    {
        cell.backgroundColor = [UIColor whiteColor];
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }

}

1
Non capisco ancora perché impostarlo in willDisplayCell fa la differenza. Si chiama comunque se lo implementiamo o no giusto?
Sharen Eayrs,

6

Dopo aver provato tutte le diverse soluzioni, il seguente metodo è il più elegante. Modificare il colore nel seguente metodo delegato:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (...){
        cell.backgroundColor = [UIColor blueColor];
    } else {
        cell.backgroundColor = [UIColor whiteColor];
    }
}

4

vlado.grigorov ha dei buoni consigli: il modo migliore è quello di creare uno sfondo e dargli un colore, impostando tutto il resto su clearColor. Inoltre, penso che sia l'unico modo per cancellare correttamente il colore (prova il suo campione - ma imposta 'clearColor' invece di 'yellowColor'), che è quello che stavo cercando di fare.


Un vantaggio di questo approccio è che puoi mantenere il colore come proprietà in fase di progettazione in Interface Builder. Un problema di progettazione in meno che richiede l'interazione degli sviluppatori.
Whitneyland,

1
cell.backgroundView = [[[UIView alloc] initWithFrame: cell.bounds] autorelease]; cell.backgroundView.backgroundColor = [UIColor redColor];
Brian,

3

La personalizzazione dello sfondo di una cella di visualizzazione tabella diventa infine l'approccio "tutto o niente". È molto difficile cambiare il colore o l'immagine utilizzati per lo sfondo di una cella di contenuto in un modo che non sembra strano.

Il motivo è che la cella si estende effettivamente sulla larghezza della vista. Gli angoli arrotondati fanno solo parte del suo stile di disegno e la vista del contenuto si trova in quest'area.

Se cambi il colore della cella del contenuto, finirai con dei bit bianchi visibili agli angoli. Se cambi il colore dell'intera cella, avrai un blocco di colore che copre la larghezza della vista.

Puoi sicuramente personalizzare una cella, ma non è così facile come potresti pensare all'inizio.


1
Questo è sicuramente vero per le celle nelle tabelle raggruppate, ma le tabelle semplici non devono preoccuparsi tanto. Una cellula disadorno senza accessori dovrebbe avere un bell'aspetto.
Ben Gottlieb,

Ben - buon punto. Uso principalmente tabelle raggruppate ma, come dici tu, le tabelle semplici non soffrono di nessuno di questi problemi.
Andrew Grant,

3

Crea una vista e impostala come vista di sfondo della cella

UIView *lab = [[UIView alloc] initWithFrame:cell.frame];
            [lab setBackgroundColor:[UIColor grayColor]];
            cell.backgroundView = lab;
            [lab release];

3

Per estendere la risposta di N.Berendt: se si desidera impostare il colore della cella in base a uno stato nell'oggetto dati cella effettivo, nel momento in cui si stanno configurando il resto delle informazioni per la cella della tabella, che è in genere quando ci si trova nella cellForRowAtIndexPath metodo, puoi farlo sovrascrivendo il metodo willDisplayCell per impostare il colore di sfondo della cella dal colore di sfondo della vista del contenuto - questo aggira il problema degli sfondi del pulsante di divulgazione ecc. non è giusto ma ti consente ancora di controllare il colore nel metodo cellForRowAtIndexPath dove stai facendo tutte le altre personalizzazioni delle celle.

Quindi: se aggiungi questo metodo al delegato della vista tabella:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = cell.contentView.backgroundColor;
}

Quindi nel tuo metodo cellForRowAtIndexPath puoi fare:

if (myCellDataObject.hasSomeStateThatMeansItShouldShowAsBlue) {
    cell.contentView.backgroundColor = [UIColor blueColor];
}

Questo evita di dover recuperare nuovamente i tuoi oggetti dati nel metodo willDisplayCell e salva anche di avere due posizioni in cui esegui la personalizzazione / personalizzazione della cella della tabella: tutta la personalizzazione può andare nel metodo cellForRowAtIndexPath.


3

Crea un'immagine da utilizzare come sfondo con Photoshop o gimp e chiamala myimage. Quindi, aggiungi questo metodo alla classe tableViewController:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    UIImage *cellImage = [UIImage imageNamed:@"myimage.png"];//myimage is a 20x50 px with  gradient  color created with gimp
    UIImageView *cellView = [[UIImageView alloc] initWithImage:cellImage];
    cellView.contentMode = UIContentViewModeScaleToFill;
    cell.backgroundView = cellView;
    //set the background label to clear
    cell.titleLabel.backgroundColor= [UIColor clearColor];
}

Questo funzionerà anche se UITableView è stato impostato su personalizzato nella finestra di ispezione degli attributi.


2

La mia soluzione è aggiungere il seguente codice all'evento cellForRowAtIndexPath:

UIView *solidColor = [cell viewWithTag:100];
if (!solidColor) {

    solidColor = [[UIView alloc] initWithFrame:cell.bounds];
    solidColor.tag = 100; //Big tag to access the view afterwards
    [cell addSubview:solidColor];
    [cell sendSubviewToBack:solidColor];
    [solidColor release];
}
solidColor.backgroundColor = [UIColor colorWithRed:254.0/255.0
                                             green:233.0/255.0
                                              blue:233.0/255.0
                                             alpha:1.0];

Funziona in qualsiasi circostanza, anche con i pulsanti di divulgazione, ed è meglio che la tua logica agisca sullo stato del colore delle celle in cellForRowAtIndexPath rispetto all'evento cellWillShow.


1

Sottoclasse UITableViewCell e aggiungerlo nell'implementazione:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}

1
    UIView *bg = [[UIView alloc] initWithFrame:cell.frame];
    bg.backgroundColor = [UIColor colorWithRed:175.0/255.0 green:220.0/255.0 blue:186.0/255.0 alpha:1]; 
    cell.backgroundView = bg;
    [bg release];

1

Funzionerà con l'ultimo Xcode.

-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    cell.backgroundColor = [UIColor grayColor];
}

0

Prova questo:

- (void)tableView:(UITableView *)tableView1 willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
    tableView1.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Cream.jpg"]];
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.