2011-11-29 11 views
22

Si configuro el atributo backgroundColor en una UITableViewCell agrupada, el color de fondo cambia correctamente. Estupendo.iOS: utilizando UIAppearance para definir el color UITableViewCell personalizado

Pero me gustaría utilizar UIAppearance para cambiar el color de fondo en todas mis UITableViewCells, por lo que puedo hacerlo en un lugar y afectar un cambio en todas partes. Aquí está mi código:

[[UITableViewCell appearance] setBackgroundColor:[UIColor colorWithRed:30.0/255.0 green:30.0/255.0 blue:30.0/255.0 alpha:1.0]]; 

UITableViewCell implementa UIAppearance y UIAppearanceContainer, por lo que habría pensado que esto funcionaría. Pero no es así También intenté usar -[UITableViewCell appearanceWhenContainedIn:(Class)], y eso tampoco funciona.

¿Alguna idea?

Respuesta

41

Actualización (2013/7/8) - Esto se ha solucionado en las versiones más nuevas de iOS. Sin embargo, vale la pena saber si te estás orientando a iOS 6 o inferior.

Puede culpar a Apple por este, y en realidad es bastante malo de ellos. Técnicamente, backgroundColorno es personalizable a través de proxies de apariencia.

De la documentación de Apple:

Para permitir la personalización apariencia, una clase debe cumplir con el protocolo UIAppearanceContainer y métodos de acceso pertinentes deben ser marcados con UI_APPEARANCE_SELECTOR.

Si entramos en una clase como UIBarButtonItem y ver la propiedad tintColor vemos esto:

@property(nonatomic,retain) UIColor *tintColor UI_APPEARANCE_SELECTOR; 

Por lo tanto, ya que está marcado con la etiqueta UI_APPEARANCE_SELECTOR sabemos que funciona con UIAppearance.

Aquí es donde Apple son particularmente media: en un UIView, backgroundColor no tiene ninguna etiqueta selector de apariencia, pero todavía funciona con UIAppearance. De acuerdo con toda la documentación que proporciona Apple, no debería, pero aún así lo hace.

Esto da la impresión engañosa de que funcionará para todas las subclases de UIView, incluido UITableView. Esto ha llegado antes, in this previous SO answer

Así que la conclusión es que backgroundColor no debe trabajar en absoluto con UIAppearance, pero por alguna razón que lo hace en un UIView. No se garantiza que funcione en las subclases UIView, y no funciona en absoluto en UITableView. ¡Lo siento, no pude darle una respuesta más positiva!

+0

Gracias por la explicación. Probablemente me habría pasado unas horas asintiendo con la cabeza contra la pared por eso. – matsr

+0

Sí, excelente respuesta. ¡Gracias! –

+0

Si esto es algo que realmente te molesta (¡me molesta!), Definitivamente presenta un informe de error con Apple. No creo que sea realmente un 'error' per se, pero definitivamente es una deficiencia. Creo que incluso he visto a alguien de Apple usar 'setBackgroundColor' en una demostración de código una vez en proxy de apariencias. – lxt

17

Puede crear su propia subclase de UITableViewCell que cumpla con UIAppearance y marque un formador personalizado con UI_APPEARANCE_SELECTOR. A continuación, establezca la celda backgroundColor en la superclase de su configurador personalizado.

En su AppDelegate

[[CustomCell appearance] setBackgroundCellColor:[UIColor redColor]]; 

En la subclase UITableView

@interface CustomCell : UITableViewCell <UIAppearance> 

@property (nonatomic, weak) UIColor *backgroundCellColor UI_APPEARANCE_SELECTOR; 

@implementation CustomCell 

@synthesize backgroundCellColor; 

-(void)setBackgroundCellColor:(UIColor *)backgroundColor 
{ 
    [super setBackgroundColor:backgroundColor]; 
} 

estoy usando ARC en este ejemplo.

+0

Incluso sin crear subclases, puede usar una categoría y propiedades personalizadas para llamadas de aparición de proxy. Puede ser útil si desea que el tema sea una parte donde no pueda usar una subclase (como para el 'UIPrintInteractionController', por ejemplo). – Tom

0

Utilicé la categoría para esto. A continuación se muestra el código de ejemplo En su archivo .h escribir

*@interface UITableViewCell (MyCustomCell) 
@property (nonatomic, weak) UIColor *backgroundCellColor UI_APPEARANCE_SELECTOR; 
@end* 

En el archivo .m escribir

*@dynamic backgroundCellColor; 
-(void)setBackgroundCellColor:(UIColor *)backgroundColor 
{ 
    [super setBackgroundColor:backgroundColor]; 
}* 

funcionó bien para mí. :) Gracias Nate !!!

3

Sin subclases! Hacer esto en una subclase probablemente NO sea la mejor práctica, especialmente si desea presionar todos los fondos de tableView. Eso es una gran cantidad de subclases. Una gran cantidad de posibles errores. Un desastre realmente. La mejor forma de hacerlo es usar una categoría. Tendrá que configurar uno para tableViewCell y tableView. Solo demostraré el de la célula. La propiedad de tableView que debe hacer es la propiedad backgroundColor. NÓTESE BIEN. Estoy anteponiendo mis métodos con "sat".

// .h

#import <UIKit/UIKit.h> 

@interface UITableViewCell (Appearance)<UIAppearance> 
@property (strong, nonatomic) UIColor *satBackgroundColor UI_APPEARANCE_SELECTOR; 
@end 

// .m

#import "UITableViewCell+Appearance.h" 

@implementation UITableViewCell (Appearance) 

- (UIColor *)satBackgroundColor 
{ 
    return self.backgroundColor; 
} 

- (void)setSatBackgroundColor:(UIColor *)satBackgroundColor 
{ 
    self.backgroundColor = satBackgroundColor; 
} 


@end 

En su AppDelegate o alguna clase gerente podrás importar la categoría y simplemente llamarlo como si tuviera una apariencia proxy incorporado.

UITableViewCell *cell = [UITableViewCell appearance]; 
cell.satBackgroundColor = [UIColor orangeColor]; 

Bien, ahora solo haga uno para la propiedad de fondo de tableView. Sencillo.

Cuestiones relacionadas