2010-05-13 15 views
25

Ich habe eine iPhone-Anwendung mit ein paar benutzerdefinierten Farben für mein Thema. Da diese Farben für meine Benutzeroberfläche korrigiert werden, möchte ich die Farben in einer Klasse definieren, die enthalten sein soll (Constants.h und Constants.m). Wie mache ich das? (Sie einfach zu definieren funktioniert nicht, weil UIColors veränderbar sind und Fehler verursachen würden - Initiator nicht konstant).Ziel C Definition UIColor Konstanten

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

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

Vielen Dank!

Antwort

42

Ein UIColor ist nicht änderbar. Normalerweise mache ich das mit Farben, Schriften und Bildern. Sie könnten es leicht ändern, um Singletons zu verwenden oder einen statischen Initialisierer zu haben.

@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 für den ersten Satz - der Initialisierer ist was nicht konstant ist, nicht die Instanz. Für alle Absichten und Zwecke könnte UIColor (oder könnte morgen) interne Zustandsvariablen enthalten, die für den Benutzer unbelichtet sind, so dass sie uns konstant erscheinen, jedoch gibt es nichts in Obj-C, das dies erzwingt. Daher kann der Compiler keinen statischen Initializer verwenden, wie es wünschenswert wäre, da [UIColor colorWithRed: 1.0 grün: 1.0 blau: 1.0 alpha: 1.0] ein Methodenaufruf ist und daher die Ergebnisse nicht in das Textsegment geschrieben werden können. welches zur Kompilierzeit erstellt wird. –

+5

Änderbar bedeutet, dass Sie die Instanz ändern können. Unveränderbar bedeutet, dass Sie die Instanz nicht ändern können. Konstante bedeutet, dass die Instanz nicht geändert werden kann. Ein UIColor ist nicht veränderlich und auch nicht konstant. Nur CFString/NSString hat wirklich konstante Instanzen, weil sie vom Compiler als Teil der Sprache behandelt werden. – drawnonward

+1

Wie verweisen Sie dann diese Farbe in Ihrem Code? – scientiffic

0

Oft setzen die Menschen globale Konstanten in Singleton Objekte - oder als drawnonward erwähnt, können Sie diese über eine Klassenmethode einer Klasse zugänglich machen.

-1

Verwenden Sie den AppController, um die Farben global statt einer statischen Variable zugänglich zu machen. Auf diese Weise macht es Sinn, von einer Architektur Standpunkt, und auch, wenn Sie Farbschemata hypothetisch ändern wollte, auch beim Laufen, würde dies nur eine Methode oder zwei auf dem

in Ihrer .h AppController

+0

AppController - Ich denke, Sie beziehen sich auf den UIApplication Delegaten ? – Till

+0

Das Ändern der Farben zur Laufzeit wäre in den meisten Anwendungen eine viel größere Aufgabe. Auch eine gute Möglichkeit, den App-Delegierten mit Code zu belästigen, der nichts damit zu tun hat. – Sulthan

13

Eine weitere Option sein Sie können

extern UIColor * const COLOR_LIGHT_BLUE; 

in Ihrem .mm tun können Sie mich dies tat

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

Was ist das für dynamische C++ - Konstanten? ;) +1 – Greg

+0

Ich bin daran interessiert, warum dies auch möglich ist. –

+0

Es ist möglich, weil 'T * const' ein konstanter Zeiger auf ein reguläres Objekt ist (Sie können nicht ändern, wo ein solcher Zeiger zeigt), im Gegensatz zu' const T * ', das ein Zeiger auf ein konstantes Objekt ist (Sie können nicht modifiziere das Objekt durch einen solchen Zeiger). –

30

Zur Vereinfachung tun:

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

Vergessen Sie nicht, das ';' Sie können es also als normalen Ausdruck verwenden.

Ich bin mir nicht sicher, ob etwas technisch falsch mit diesem Ansatz ist, aber es funktioniert gut, und vermeidet die Kompilierungszeit Konstante Initialisierungsfehler - dieser Code ist effektiv an Ort und Stelle fest, wo Sie 'myColor' setzen, so tut es nicht werde nie kompiliert, bis du es benutzt hast.

+0

interessanter Ansatz! Ich wäre interessiert, warum das ";" kann weggelassen werden? Wie heißt das? – brainray

+2

Es ist ein Präprozessor-Makro. Effektiv wird 'myColor' ersetzt, wo immer es in Ihrem Code mit der vollständigen Zeile '[UIColor colorWith ...' erscheint, bevor es kompiliert wird. Du lässt das ';' Im Makro können Sie also den Code wie folgt verwenden: 'UIColor * color = myColor;' anstelle von 'UIColor * color = myColor', das nicht wie eine normale Codezeile aussieht (es ist natürlicher, ein Semikolon zu platzieren) das Ende einer beliebigen Codezeile). Es kann weggelassen werden, weil Präprozessor-Makros so ausgewertet werden, wie sie sind, wenn sie verwendet werden. Solange Sie also ein Semikolon in Ihren tatsächlichen Code einfügen, geht es Ihnen gut. –

+2

Aber erstellt dies nicht jedes Mal eine neue Instanz dieser Farbe, wenn Sie dieses Makro verwenden? Erwägen Sie, es in einer for-Schleife mit 1000 Iterationen zu haben, und weisen Sie es einer Ansicht als Hintergrundfarbe zu. Das ist nicht sehr effizient, oder? – Majster

3

Wenn Sie sich für eine schnelle und schmutzige ohne Erweiterungen gehen mit clang suchen:

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

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

} 
+0

Super Code, danke! – Genevios

0

Hier ist eine andere Art und Weise:

Rubrik:

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

COLORS_EXTERN UIColor *aGlobalColor; 

Umsetzung:

#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 ist ein bisschen ein Hack, aber Sie müssen die Farbe in der Implementierung nicht neu definieren, und Sie können auf Farben ohne einen Methodenaufruf zugreifen.