2010-05-13 17 views
25

Tengo una aplicación para iPhone con algunos colores personalizados para mi tema. Como estos colores se fijarán para mi UI, me gustaría definir los colores en una clase para incluir (Constantes.h y Constantes.m). ¿Cómo puedo hacer eso? (Simplemente definirlos no funciona porque los UIColors son mutables y causarían errores, Initalizer no es constante).Objetivo C que define las constantes UIColor

/* Constants.h */ 
extern UIColor *test; 

/* Constants.m */ 
UIColor *test = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]; 

Gracias!

Respuesta

42

Un UIColor no se puede modificar. Normalmente hago esto con colores, fuentes e imágenes. Podrías modificarlo fácilmente para usar singletons o tener un inicializador estático.

@interface UIColor (MyProject) 

+(UIColor *) colorForSomePurpose; 

@end 

@implementation UIColor (MyProject) 

+(UIColor *) colorForSomePurpose { return [UIColor colorWithRed:0.6 green:0.8 blue:1.0 alpha:1.0]; } 

@end 
+1

-1 para la primera frase: el inicializador es lo que no es constante, no es la instancia. Para todos los efectos, UIColor podría (o podría mañana) contener variables de estado internas que no están expuestas al usuario, haciéndonos parecer constantes, sin embargo, no hay nada en Obj-C que lo fuerce. Por lo tanto, el compilador no puede usar un inicializador estático, como le gustaría, porque [UIColor colorWithRed: 1.0 verde: 1.0 azul: 1.0 alfa: 1.0] es una llamada a método, y por lo tanto los resultados de esto no se pueden poner en el segmento de texto, que se crea en tiempo de compilación. –

+5

Mutable significa que puede cambiar la instancia. Inmutable significa que no puede cambiar la instancia. Constante significa que la instancia no se puede cambiar. Un UIColor no es mutable y tampoco constante. Solo CFString/NSString tiene instancias verdaderamente constantes porque el compilador las maneja especialmente como parte del lenguaje. – drawnonward

+1

¿cómo hace referencia a este color en su código? – scientiffic

0

A menudo la gente poner las constantes globales en objetos únicos - o como drawnonward señaló, puede que sean accesibles a través de un método de la clase de alguna clase.

-1

Utilice AppController para hacer que los colores sean accesibles globalmente, en lugar de una variable estática. De esa manera que tiene sentido desde un punto de vista arquitectura, y también si usted quiere cambiar hipotéticamente esquemas de color, incluso mientras se ejecuta, esto sólo sería un método o dos en el AppController

+0

AppController - Supongo que se está refiriendo al delegado UIApplication ? – Till

+0

Cambiar colores en tiempo de ejecución sería una tarea mucho más grande en la mayoría de las aplicaciones. También es una buena forma de contaminar al delegado de la aplicación con un código que no tiene nada que ver con eso. – Sulthan

13

Otra opción

en su .h que puede hacer

extern UIColor * const COLOR_LIGHT_BLUE; 

en su .mm que puede hacer

UIColor* const COLOR_LIGHT_BLUE = [[UIColor alloc] initWithRed:21.0f/255 green:180.0f/255 blue:1 alpha:1];//;#15B4FF 
+3

¿Qué significan estas constantes dinámicas de C++? ;) +1 – Greg

+0

Estoy interesado en por qué esto también es posible. –

+0

Es posible, porque 'T * const' es un puntero constante a un objeto normal (no se puede modificar hacia dónde apunta ese puntero), en oposición a' const T * ', que es un puntero a un objeto constante (no se puede modificar el objeto a través de dicho puntero). –

30

Por simplicidad hizo esto:

/* Constants.h */ 
#define myColor [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0] 

No olvides dejar afuera el ';' para que pueda usarlo como una expresión normal.

No estoy seguro de si hay algo técnicamente incorrecto con este enfoque, pero funciona bien, y evita el error de inicialización constante en tiempo de compilación: este código está efectivamente pegado en cualquier lugar donde coloque 'myColor', por lo que no lo hace Nunca se compilará hasta que realmente lo use.

+0

enfoque interesante! Me interesaría por qué el ';' puede ser dejado afuera? ¿Cómo se llama esto? – brainray

+2

Es una macro de preprocesador. Efectivamente 'myColor' se reemplaza donde aparezca en su código con la línea de código '[UIColor colorWith ...' completa, antes de que se compile. Usted deja de lado el ';' en la macro para que pueda usar el código de esta manera: 'UIColor * color = myColor;' en lugar de 'UIColor * color = myColor', que no se parece a una línea normal de código (es más natural colocar un punto y coma en el final de cualquier línea de código). Puede omitirse porque las macros de preprocesador se evalúan tal como son cuando se usan, de modo que, mientras coloque un punto y coma en su código real, estará bien. –

+2

¿Pero esto no crea una nueva instancia de este color cada vez que utiliza esta macro? Considere tenerlo en un bucle for con 1000 iteraciones y asignarlo como color de fondo a una vista. Esto no es muy eficiente ¿verdad? – Majster

3

Si usted está buscando una rápida y sucia sin extensiones ir con clang:

#define kGreenColor colorWithRed:(0/255.0) green:(213/255.0) blue:(90/255.0) alpha:1.0 

- (void)doSomething 
{ 
    _label.textColor = [UIColor kGreenColor]; 

} 
+0

¡Código impresionante, gracias! – Genevios

0

Ésta es otra manera:

Cabecera:

#if !defined(COLORS_EXTERN) 
    #define COLORS_EXTERN extern 
#endif 

COLORS_EXTERN UIColor *aGlobalColor; 

Implementación:

#define COLORS_EXTERN 
#import "GlobalColors.h" 


@interface GlobalColors : NSObject 
@end 

@implementation GlobalColors 

+ (void)load 
{ 
    aGlobalColor = [UIColor colorWithRed:0.2 green:0.3 blue:0.4 alpha:1]; 
} 

@end 

Es un truco, pero no necesita redefinir el color en la implementación y puede acceder a los colores sin una llamada a un método.