¿Cómo personalizar el color de fondo de un UITableViewCell?

188

Me gustaría personalizar el fondo (y quizás el borde también) de todos los UITableViewCells dentro de mi UITableView. Hasta ahora no he podido personalizar estas cosas, así que tengo un montón de celdas de fondo blanco, que es el valor predeterminado.

¿Hay alguna manera de hacer esto con el SDK de iPhone?

jpm
fuente

Respuestas:

193

Debe establecer el color de fondo del contenido de la celda en su color. Si usa accesorios (como flechas de revelación, etc.), aparecerán en blanco, por lo que es posible que tenga que rodar versiones personalizadas de ellos.

Ben Gottlieb
fuente
108
por ejemplo, myCell.contentView.backgroundColor = [UIColor greenColor];
JoBu1324
1
La respuesta de vlado.grigorov es más flexible - ver la respuesta de William Denniss
JoBu1324
3
¿Algún enlace sobre cómo rodar uno UITableViewCellAccessoryCheckmark, por ejemplo? Gracias.
Dan Rosenstark
66
Para verlo a veces necesitas configurar:cell.textLabel.backgroundColor = [UIColor clearColor];
Evan Moran
205

Esta es la forma más eficiente que he encontrado para resolver este problema, use el método delegado willDisplayCell (esto también se encarga del color blanco para el fondo de la etiqueta de texto al usar cell.textLabel.text y / o cell.detailTextLabel.text ):

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

Cuando se llama a este método delegado, el color de la celda se controla a través de la celda en lugar de la vista de tabla, como cuando usa:

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

Entonces, dentro del cuerpo del método de delegado de celda, agregue el siguiente código para alternar los colores de las celdas o simplemente use la llamada a la función para hacer que todas las celdas de la tabla tengan el mismo color.

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

Esta solución funcionó bien en mi circunstancia ...

Nathan B.
fuente
Esta es una solución mucho más limpia. La mayoría de las otras soluciones requieren subclasificar UITableViewCell. La solución de vlado.grigorov no funciona para mí.
Ronnie Liew
De hecho, y este es el método que Apple mismo recomienda de acuerdo con varias presentaciones de WWDC que he visto.
Mike Weller
Agradable: EXCEPTO cuando necesite agregar nuevas filas en la parte superior de la lista. Este método hace todas las adiciones del mismo color. La actualización lo soluciona, pero lleva tiempo innecesario. Descubierto ayer ...
JOM
Esto parece funcionar bien, excepto cuando se usa Core Data. Las nuevas celdas agregadas a través de un NSFetchedResultsController no parecen llamar a willDisplayCell correctamente. Estoy en una pérdida de hacer que funcione ...
radven
La línea equivalente para configurar el color de fondo en Swift 2.0:cell.backgroundColor = UIColor.clearColor
kbpontius
104

Esto es realmente simple, ya que OS 3.0 simplemente establece el color de fondo de la celda en el método willDisplayCell. No debe establecer el color en cellForRowAtIndexPath.

Esto funciona tanto para el estilo plano como para el agrupado:

Código:

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

PD: Aquí el extracto de documentación para willDisplayCell:

"Una vista de tabla envía este mensaje a su delegado justo antes de que use la celda para dibujar una fila, permitiendo así que el delegado personalice el objeto de la celda antes de que se muestre. Este método le da al delegado la oportunidad de anular las propiedades basadas en estado establecidas anteriormente por la vista de tabla, como la selección y el color de fondo. Después de que el delegado regresa, la vista de tabla establece solo las propiedades alfa y marco, y luego solo al animar filas a medida que se deslizan hacia adentro o hacia afuera ".

He encontrado esta información en esta publicación de colionel . ¡Gracias a el!

Seba
fuente
3
Esto debe marcarse como la respuesta correcta, ya que ni siquiera tiene que hacer nada si tiene una divulgación
Indicador
1
Esto no funciona si desea un color de fondo de celda diferente al de las vistas de tabla para mí.
Chris
Para la celda grupal, puede configurarlo en cellForRow
Sharen Eayrs el
58

El mejor enfoque que he encontrado hasta ahora es establecer una vista de fondo de la celda y borrar el fondo de las subvistas de la celda. Por supuesto, esto se ve bien en tablas con estilo indexado solamente, sin importar con o sin accesorios.

Aquí hay una muestra en la que el fondo de la celda está pavimentado en amarillo:

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
fuente
1
Si hace esto, asegúrese de establecer la propiedad opaca en NO también.
Lily Ballard
11
Realmente no se recomienda el uso de controles de celda transparentes. El rendimiento del desplazamiento se verá muy afectado, por lo que Apple siempre dice que use controles opacos.
Mike Weller el
3
En iOS 4.2 y posterior parece que el ciclo ya no es necesario.
Frank Schmitt
Muy agradable. ¡Funciona perfecto cuando se usan vistas accesorias!
RyanG
19

Simplemente ponga esto en su archivo de clase de delegado 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;
}
PUNTA
fuente
7

Estoy de acuerdo con Seba, traté de configurar mi color de fila alternativo en el método de delegado rowForIndexPath pero estaba obteniendo resultados inconsistentes entre 3.2 y 4.2. Lo siguiente funcionó muy bien para mí.

- (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
fuente
1
Aún no entiendo por qué configurarlo en willDisplayCell hace alguna diferencia. Se llama de todos modos si implementamos eso o no, ¿verdad?
Sharen Eayrs
6

Después de probar todas las soluciones diferentes, el siguiente método es el más elegante. Cambie el color en el siguiente método delegado:

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

vlado.grigorov tiene algunos buenos consejos: la mejor manera es crear una vista de fondo y darle un color, configurando todo lo demás en clearColor. Además, creo que esa es la única forma de borrar correctamente el color (pruebe su muestra, pero establezca 'clearColor' en lugar de 'yellowColor'), que es lo que estaba tratando de hacer.

William Denniss
fuente
Una ventaja de este enfoque es que puede mantener el color como una propiedad de tiempo de diseño en Interface Builder. Un problema de diseño menos que requiere la interacción del desarrollador.
whitneyland
1
cell.backgroundView = [[[UIView alloc] initWithFrame: cell.bounds] autorelease]; cell.backgroundView.backgroundColor = [UIColor redColor];
Brian
3

Personalizar el fondo de una celda de vista de tabla finalmente se convierte en un enfoque de "todo o nada". Es muy difícil cambiar el color o la imagen utilizada para el fondo de una celda de contenido de una manera que no se vea extraña.

La razón es que la celda realmente abarca el ancho de la vista. Las esquinas redondeadas son solo parte de su estilo de dibujo y la vista de contenido se encuentra en esta área.

Si cambia el color de la celda de contenido, terminará con bits blancos visibles en las esquinas. Si cambia el color de toda la celda, tendrá un bloque de color que abarcará el ancho de la vista.

Definitivamente puede personalizar una celda, pero no es tan fácil como podría pensar al principio.

Andrew Grant
fuente
1
Esto definitivamente es cierto para las celdas en las tablas agrupadas, pero las tablas simples no tienen tanto de qué preocuparse. Una celda sin adornos sin accesorios debería verse bien.
Ben Gottlieb
Ben: buen punto. Principalmente uso tablas agrupadas, pero como mencionas, las tablas simples no sufren ninguno de estos problemas.
Andrew Grant
3

Cree una vista y configúrela como vista de fondo de la celda.

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

Para ampliar la respuesta de N.Berendt: si desea establecer el color de la celda en función de algún estado en el objeto de datos de celda real, en el momento en que está configurando el resto de la información para la celda de la tabla, que generalmente es cuando está en el El método cellForRowAtIndexPath, puede hacerlo anulando el método willDisplayCell para establecer el color de fondo de la celda desde el color de fondo de la vista de contenido; esto evita el problema de que los fondos del botón de divulgación, etc., no sean correctos, pero aún le permiten controlar el color en el método cellForRowAtIndexPath donde está haciendo toda la personalización de su otra celda.

Entonces: si agrega este método a su delegado de vista de tabla:

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

Luego, en su método cellForRowAtIndexPath puede hacer:

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

Esto ahorra tener que recuperar sus objetos de datos nuevamente en el método willDisplayCell y también ahorra tener dos lugares donde se personaliza / personaliza la celda de la tabla: toda la personalización puede ir en el método cellForRowAtIndexPath.

gamozzii
fuente
3

Cree una imagen para usar como fondo con Photoshop o gimp y asígnele el nombre myimage. Luego, agregue este método a su clase 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];
}

Esto también funcionará si ha configurado UITableView como personalizado en el inspector de atributos.

Davide
fuente
2

Mi solución es agregar el siguiente código al 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];

Funciona bajo cualquier circunstancia, incluso con botones de divulgación, y es mejor para su lógica actuar sobre el estado del color de las celdas en cellForRowAtIndexPath que en el evento cellWillShow, creo.

albertoFlagSolutions
fuente
1

Subclase UITableViewCell y agregue esto en la implementación:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}
Jonás Gabriel
fuente
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
fuente
1

Esto funcionará en el último Xcode.

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

Prueba esto:

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