2012-07-03 18 views
13

Hemos extendido UILabel para poder aplicar fuentes y colores estándar para todos los usos de un tipo de etiqueta determinado en nuestras aplicaciones. P.ej.UIAppearance no tiene efecto en UILabels creado programáticamente

@interface UILabelHeadingBold : UILabel 
@end 

En nuestra AppDelegate, aplicamos fuentes y colores como esto

[[UILabelHeadingBold appearance] setTextColor:<some color>]; 
[[UILabelHeadingBold appearance] setFont:<some font>]; 

Al añadir un UILabel en nuestros de XIB, ahora puede seleccionar la clase a ser de tipo UILabelHeadingBold, y funciona como se esperaba . La etiqueta se muestra con la fuente y el color correctos, tal como se especifica en nuestro AppDelegate.

Sin embargo, si creamos una etiqueta mediante programación, p. Ej.

UILabelHeadingBold *headingLabel = [[UILabelHeadingBold alloc] initWithFrame:CGRectMake(10, 10, 100, 30)]; 
[self.mainView addSubview:headingLabel]; 

UILabel no obtiene la fuente/color esperados. Tenemos que aplicar manualmente estos atributos.

¿Hay alguna manera de hacer que UIAppearance tenga efecto en los elementos de UI creados por programación, o solo funciona cuando se usa dentro de los XIB?

Respuesta

17

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.

Por ejemplo, en UINavigationBar.h, tintColor está marcado con UI_APPEARANCE_SELECTOR

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

Pero en UILabel.h se puede ver que los textColor y font propertys no están marcados con UI_APPEARANCE_SELECTOR pero de alguna manera funciona cuando se añade en la interfaz Constructor (siguiendo la documentación, no debería funcionar en absoluto).

+2

Es * no * a veces trabajan para UILabels creados en código también, pero los resultados son inconsistentes, y el comportamiento es diferente entre iOS 5 y, bueno, ya sabes. Así que simplemente no use 'UIAppearance' para personalizar' UILabel's –

+0

+1 para la información, que no soy el único que obtiene resultados inconsistentes (me tomó horas de codificación hasta que encontré su comentario). +1 para la solución robert.wijas, que uso ahora, y todo está bien. – anneblue

14

El truco simple que funciona sin problemas es crear una categoría con un ajustador UIAppearance que modifique las propiedades de UILabel.

siguientes convenciones UIAppearance yo creamos un método:

- (void)setTextAttributes:(NSDictionary *)numberTextAttributes; 
{ 
    UIFont *font = [numberTextAttributes objectForKey:UITextAttributeFont]; 
    if (font) { 
     self.font = font; 
    } 
    UIColor *textColor = [numberTextAttributes objectForKey:UITextAttributeTextColor]; 
    if (textColor) { 
     self.textColor = textColor; 
    } 
    UIColor *textShadowColor = [numberTextAttributes objectForKey:UITextAttributeTextShadowColor]; 
    if (textShadowColor) { 
     self.shadowColor = textShadowColor; 
    } 
    NSValue *shadowOffsetValue = [numberTextAttributes objectForKey:UITextAttributeTextShadowOffset]; 
    if (shadowOffsetValue) { 
     UIOffset shadowOffset = [shadowOffsetValue UIOffsetValue]; 
     self.shadowOffset = CGSizeMake(shadowOffset.horizontal, shadowOffset.vertical); 
    } 
} 

En la categoría UILabel:

@interface UILabel (UISS) 

- (void)setTextAttributes:(NSDictionary *)numberTextAttributes UI_APPEARANCE_SELECTOR; 

@end 

Todavía estoy tratando de averiguar por qué la incubadora original no funciona.

+0

Creamos propiedades personalizadas en una subclase que funciona con el proxy de apariencia. P.ej. una propiedad "titleLabelFont" para envolver la propiedad titleLabel.font de UIButton. Funciona también para otras propiedades, como sombras. –

+0

@robert +1 muy buena solución. Me llevó horas codificando hasta que encontré tu respuesta. Gracias por eso. Ahora, todo funciona bien (y simple). – anneblue

+0

Gran solución, esto funciona bien en otras vistas también, como UIButton para establecer la fuente titleLabel como Apple desaprobó el método setFont :. –

0

@ robert.wijas solución funciona muy bien!

Para iOS 7 y hacia arriba tuve que actualizar la clave desde la que utiliza no son aprobadas por 7+:

- (void)setTextAttributes:(NSDictionary *)numberTextAttributes; 
{ 
    UIFont *font = [numberTextAttributes objectForKey:NSFontAttributeName]; 
    if (font) { 
     self.font = font; 
    } 
    UIColor *textColor = [numberTextAttributes objectForKey:NSForegroundColorAttributeName]; 
    if (textColor) { 
     self.textColor = textColor; 
    } 
    UIColor *textShadowColor = [numberTextAttributes objectForKey:NSShadowAttributeName]; 
    if (textShadowColor) { 
     self.shadowColor = textShadowColor; 
    } 
    NSValue *shadowOffsetValue = [numberTextAttributes objectForKey:NSShadowAttributeName]; 
    if (shadowOffsetValue) { 
     UIOffset shadowOffset = [shadowOffsetValue UIOffsetValue]; 
     self.shadowOffset = CGSizeMake(shadowOffset.horizontal, shadowOffset.vertical); 
    } 
} 
+0

Tenga en cuenta que no está manejando el atributo NSShadowAttributeName correctamente; su valor es NSShadow. –

Cuestiones relacionadas