Comment personnaliser la couleur de fond d'un UITableViewCell?

188

Je voudrais personnaliser l'arrière-plan (et peut-être la bordure aussi) de toutes les UITableViewCells dans mon UITableView. Jusqu'à présent, je n'ai pas été en mesure de personnaliser ce truc, j'ai donc un tas de cellules de fond blanc qui est la valeur par défaut.

Existe-t-il un moyen de le faire avec le SDK iPhone?

jpm
la source

Réponses:

193

Vous devez définir la couleur backgroundColor du contentView de la cellule sur votre couleur. Si vous utilisez des accessoires (tels que des flèches de divulgation, etc.), ils apparaîtront en blanc, vous devrez donc peut-être en rouler des versions personnalisées.

Ben Gottlieb
la source
108
par exemple myCell.contentView.backgroundColor = [UIColor greenColor];
JoBu1324 le
1
La réponse de vlado.grigorov est plus flexible - voir la réponse de William Denniss
JoBu1324
3
Des liens sur la façon de rouler le sien UITableViewCellAccessoryCheckmark, par exemple? Merci.
Dan Rosenstark
6
Pour le voir parfois, vous devez définir:cell.textLabel.backgroundColor = [UIColor clearColor];
Evan Moran
205

Voici le moyen le plus efficace que j'ai rencontré pour résoudre ce problème, utilisez la méthode de délégation willDisplayCell (cela prend également en charge la couleur blanche pour l'arrière-plan de l'étiquette de texte lorsque vous utilisez cell.textLabel.text et / ou cell.detailTextLabel.text ):

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

Lorsque cette méthode déléguée est appelée, la couleur de la cellule est contrôlée via la cellule plutôt que la vue tableau, comme lorsque vous utilisez:

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

Ainsi, dans le corps de la méthode de délégué de cellule, ajoutez le code suivant pour alterner les couleurs des cellules ou utilisez simplement l'appel de fonction pour que toutes les cellules du tableau aient la même couleur.

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

Cette solution a bien fonctionné dans ma situation ...

Nathan B.
la source
C'est une solution plus propre. La plupart des autres solutions nécessitent de sous-classer UITableViewCell. La solution de vlado.grigorov ne fonctionne pas pour moi.
Ronnie Liew
En effet, et c'est la méthode qu'Apple lui-même recommande selon diverses présentations de la WWDC que j'ai vues.
Mike Weller
Nice - SAUF lorsque vous devez ajouter de nouvelles lignes en haut de la liste. Cette méthode rend tous les ajouts de la même couleur. L'actualisation résout le problème, mais prend un temps inutile.
Découvert
Cela semble bien fonctionner, sauf lors de l'utilisation de Core Data. Les nouvelles cellules ajoutées via un NSFetchedResultsController ne semblent pas appeler willDisplayCell correctement. Je suis perdu pour que ça marche ...
radven
La ligne équivalente pour définir la couleur d'arrière-plan dans Swift 2.0:cell.backgroundColor = UIColor.clearColor
kbpontius
104

C'est vraiment simple, puisque OS 3.0 définit simplement la couleur d'arrière-plan de la cellule dans la méthode willDisplayCell. Vous ne devez pas définir la couleur dans le cellForRowAtIndexPath.

Cela fonctionne à la fois pour le style simple et groupé:

Code:

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

PS: Voici l'extrait de documentation de willDisplayCell:

"Une vue de tableau envoie ce message à son délégué juste avant d'utiliser la cellule pour dessiner une ligne, permettant ainsi au délégué de personnaliser l'objet de la cellule avant son affichage. Cette méthode donne au délégué la possibilité de remplacer les propriétés basées sur l'état définies précédemment par la vue de tableau, telle que la sélection et la couleur d'arrière-plan. Une fois que le délégué est revenu, la vue de tableau définit uniquement les propriétés alpha et de cadre, et uniquement lors de l'animation des lignes lorsqu'elles glissent vers l'intérieur ou vers l'extérieur. "

J'ai trouvé ces informations dans ce post de colionel . Merci!

Seba
la source
3
Cela devrait être marqué comme la bonne réponse car vous n'avez même rien à faire si vous avez une divulgationIndiateur
Ashish Awaghad
1
Cela ne fonctionne pas si vous voulez une couleur d'arrière-plan de cellule différente de l'arrière-plan des vues de tableau pour moi.
Chris
Pour la cellule de groupe, vous pouvez le définir sur cellForRow
Sharen Eayrs
58

La meilleure approche que j'ai trouvée jusqu'à présent consiste à définir une vue d'arrière-plan de la cellule et un arrière-plan clair des sous-vues de cellule. Bien sûr, cela a fière allure sur les tables avec un style indexé uniquement, avec ou sans accessoires.

Voici un exemple où l'arrière-plan de la cellule est haleté en jaune:

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 ];
}
Vladimir Grigorov
la source
1
Si vous faites cela, assurez-vous de définir également la propriété opaque sur NO.
Lily Ballard
11
L'utilisation de contrôles de cellule transparents n'est vraiment pas recommandée. Les performances de défilement seront beaucoup affectées, c'est pourquoi Apple recommande toujours d'utiliser des contrôles opaques.
Mike Weller
3
Sur iOS 4.2 et versions ultérieures, il semble que la boucle n'est plus nécessaire.
Frank Schmitt
Très agréable. Fonctionne parfaitement lors de l'utilisation de vues accessoires !!
RyanG
19

Mettez simplement ceci dans votre fichier de classe délégué 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;
}
POINTE
la source
7

Je suis d'accord avec Seba, j'ai essayé de définir ma couleur de ligne alternée dans la méthode de délégué rowForIndexPath mais obtenais des résultats incohérents entre 3.2 et 4.2. Ce qui suit a très bien fonctionné pour moi.

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

}
cipherz
la source
1
Je ne comprends toujours pas pourquoi le configurer dans willDisplayCell fait une différence. Cela s'appelle de toute façon, que nous appliquions cela ou non?
Sharen Eayrs
6

Après avoir essayé toutes les différentes solutions, la méthode suivante est la plus élégante. Modifiez la couleur dans la méthode de délégué suivante:

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

vlado.grigorov a quelques bons conseils - le meilleur moyen est de créer un backgroundView et de lui donner une couleur, en définissant tout le reste sur clearColor. De plus, je pense que c'est le seul moyen d'effacer correctement la couleur (essayez son échantillon - mais définissez «clearColor» au lieu de «yellowColor»), ce que j'essayais de faire.

William Denniss
la source
Un avantage de cette approche est que vous pouvez conserver la couleur comme propriété au moment du design dans Interface Builder. Un problème de conception en moins qui nécessite une interaction avec le développeur.
whitneyland
1
cell.backgroundView = [[[UIView alloc] initWithFrame: cell.bounds] autorelease]; cell.backgroundView.backgroundColor = [UIColor redColor];
Brian
3

La personnalisation de l'arrière-plan d'une cellule de vue de tableau devient finalement une approche «tout ou rien». Il est très difficile de changer la couleur ou l'image utilisée pour l'arrière-plan d'une cellule de contenu d'une manière qui ne semble pas étrange.

La raison en est que la cellule couvre en fait la largeur de la vue. Les coins arrondis font simplement partie de son style de dessin et la vue du contenu se trouve dans cette zone.

Si vous changez la couleur de la cellule de contenu, vous vous retrouverez avec des bits blancs visibles dans les coins. Si vous changez la couleur de la cellule entière, vous aurez un bloc de couleur couvrant la largeur de la vue.

Vous pouvez certainement personnaliser une cellule, mais ce n'est pas aussi facile que vous ne le pensez au début.

Andrew Grant
la source
1
Cela est certainement vrai pour les cellules des tableaux groupés, mais les tableaux simples n'ont pas autant de souci à se faire. Une cellule sans ornements sans accessoires devrait avoir l'air bien.
Ben Gottlieb
Ben - bon point. J'utilise principalement des tableaux groupés, mais comme vous le mentionnez, les tableaux simples ne souffrent d'aucun de ces problèmes.
Andrew Grant
3

Créez une vue et définissez-la comme vue d'arrière-plan de la cellule

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

Pour prolonger la réponse de N.Berendt - Si vous souhaitez définir la couleur de cellule en fonction d'un état dans l'objet de données de cellule réel, au moment où vous configurez le reste des informations pour la cellule du tableau, ce qui est généralement lorsque vous êtes dans le cellForRowAtIndexPath, vous pouvez le faire en remplaçant la méthode willDisplayCell pour définir la couleur d'arrière-plan de la cellule à partir de la couleur d'arrière-plan de la vue du contenu - cela permet de contourner le problème des arrière-plans du bouton de divulgation, etc. où vous effectuez toutes vos autres personnalisations de cellules.

Donc: si vous ajoutez cette méthode à votre délégué de vue table:

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

Ensuite, dans votre méthode cellForRowAtIndexPath, vous pouvez faire:

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

Cela évite d'avoir à récupérer à nouveau vos objets de données dans la méthode willDisplayCell et vous évite également d'avoir deux endroits où vous pouvez personnaliser / personnaliser votre cellule de tableau - toute la personnalisation peut aller dans la méthode cellForRowAtIndexPath.

gamozzii
la source
3

Créez une image à utiliser comme arrière-plan avec Photoshop ou gimp et nommez-la myimage. Ensuite, ajoutez cette méthode à votre 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];
}

Cela fonctionnera également si vous avez défini UITableView sur personnalisé dans l'inspecteur d'attributs.

Davide
la source
2

Ma solution consiste à ajouter le code suivant à l'événement 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];

Fonctionne en toutes circonstances, même avec des boutons de divulgation, et il est préférable pour votre logique d'agir sur l'état de couleur des cellules dans cellForRowAtIndexPath que dans l'événement cellWillShow, je pense.

albertoFlagSolutions
la source
1

Sous-classe UITableViewCell et ajoutez ceci dans l'implémentation:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}
JonasGabriel
la source
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];
Bhavesh Nayi
la source
1

Cela fonctionnera dans le dernier Xcode.

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

Essaye ça:

- (void)tableView:(UITableView *)tableView1 willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
    tableView1.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Cream.jpg"]];
}
Serrement
la source