Objective C definiert UIColor-Konstanten

Lesezeit: 5 Minuten

Ich habe eine iPhone-Anwendung mit einigen benutzerdefinierten Farben für mein Thema. Da diese Farben für meine Benutzeroberfläche festgelegt werden, möchte ich die Farben in einer einzuschließenden Klasse definieren (Constants.h und Constants.m). Wie mache ich das? (Sie einfach zu definieren funktioniert nicht, weil UIColors änderbar sind und Fehler verursachen würden – Initalizer nicht konstant).

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

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

Vielen Dank!

Eine UIColor ist nicht änderbar. Normalerweise mache ich das mit Farben, Schriftarten 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 für den ersten Satz – der Initializer ist das, was nicht konstant ist, nicht die Instanz. In jeder Hinsicht könnte UIColor (oder könnte es morgen) interne Zustandsvariablen enthalten, die dem Benutzer nicht zugänglich sind, wodurch sie uns konstant erscheinen, aber es gibt nichts in Obj-C, das dies erzwingt. Daher kann der Compiler keinen statischen Initialisierer verwenden, wie er möchte, weil [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0] ist ein Methodenaufruf, und daher können die Ergebnisse davon nicht in das Textsegment eingefügt werden, das zur Kompilierzeit erstellt wird.

    – Jared Pochtar

    13. Mai 2010 um 4:28 Uhr

  • Mutable bedeutet, dass Sie die Instanz ändern können. Unveränderlich bedeutet, dass Sie die Instanz nicht ändern können. Konstant bedeutet, dass die Instanz nicht geändert werden kann. Eine UIColor ist nicht änderbar und auch nicht konstant. Nur CFString/NSString hat wirklich konstante Instanzen, da sie vom Compiler speziell als Teil der Sprache behandelt werden.

    – nach vorne gezogen

    13. Mai 2010 um 15:32 Uhr

  • Können Sie bitte erklären, was (MyProject) ist? Ich versuche, es in einer NSObject-basierten Klasse zu verwenden, und die Syntax lautet @interface Common: NSObject

    – Naveed Abbas

    9. Oktober 2017 um 6:25 Uhr

  • @ToughGuy – es ist eine Erweiterung. Die Meldung “MyProject” ist etwas irrelevant, aber notwendig (ich weiß nicht warum, aber Sie habe ich verwendet (extension) stattdessen), damit Sie es dort behalten können. Verwenden Sie so: [UIColor colorForSomePurpose] genau wie du rot würdest [UIColor red] und ETC. [self.view setBackgroundColor: [UIColor colorForSomePurpose] ];

    – App-Entwickler

    17. Oktober 2017 um 8:21 Uhr


Der Einfachheit halber habe ich das so gemacht:

/* 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 an diesem Ansatz technisch etwas falsch ist, aber er funktioniert gut und vermeidet den konstanten Initialisierungsfehler zur Kompilierzeit – dieser Code bleibt praktisch überall dort hängen, wo Sie “myColor” einfügen, sodass er niemals angezeigt wird kompiliert, bis Sie es tatsächlich verwenden.

  • interessanter Ansatz! Mich würde interessieren warum das ‘;’ kann weggelassen werden? Wie heißt das?

    – Brainray

    29. Dezember 2013 um 18:57 Uhr

  • Es ist ein Präprozessor-Makro. Effektiv wird „myColor“ überall dort, wo es in Ihrem Code erscheint, durch das vollständige „[UIColor colorWith… ‘ line of code, before it ever compiles. You leave out the ‘;’ in the macro so you can use the code like this: UIColor *color = myColor; rather than UIColor *color = myColor, which doesn’t look like a normal line of code (it’s more natural to place a semicolon at the end of any line of code). It can be left out because preprocessor macros are evaluated as they are when they’re used, so as long as you place a semicolon in your actual code, you’re fine.

    – Fateh Khalsa

    Dec 30, 2013 at 20:26


  • But doesn’t this create a new instance of this color every time you use this macro? Consider having it in a for loop with 1000 iterations and assigning it as a background color to a view. This is not very efficient is it?

    – Majster

    Jan 5, 2014 at 17:20

  • That is true, but where are you ever going to use this 1000 times? Also, if you were to create the colors normally, it would be the same case. This just allows you the convenience of defining the color once so it can be changed easily. The other methods mentioned in answers here will of course avoid creating those multiple instances, but they are more work to implement and less elegant in my opinion. The actual overhead incurred from the number of times you are likely to use this in a view should be negligible. Just my two cents FWIW though.

    – Fateh Khalsa

    Mar 20, 2014 at 18:06

Another option

in your .h you can do

extern UIColor *  const COLOR_LIGHT_BLUE;

in your .mm you can do

UIColor* const COLOR_LIGHT_BLUE = [[UIColor alloc] initWithRed:21.0f/255 grün:180.0f/255 blau:1 alpha:1];//;#15B4FF

  • Was sind diese zwielichtigen dynamischen C++-Konstanten? 😉 +1

    – Greg

    16. April 2012 um 13:27 Uhr


  • Warum das möglich ist, interessiert mich auch.

    – Taketo Sano

    9. Juli 2013 um 3:49 Uhr

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

    – Daniel S.

    2. August 2013 um 4:31 Uhr

Benutzer-Avatar
AmitP

Wenn Sie nach einem schnellen und schmutzigen ohne Erweiterungen suchen, gehen Sie mit klirren:

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

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

}

Oft fügen Leute globale Konstanten in Singleton-Objekte ein – oder, wie weiter unten angemerkt, können Sie sie über eine Klassenmethode einer Klasse zugänglich machen.

Benutzer-Avatar
götz

Hier ist ein anderer Weg:

Header:

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

COLORS_EXTERN UIColor *aGlobalColor;

Implementierung:

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

Benutzer-Avatar
Jared Pochtar

Verwenden Sie den AppController, um die Farben global zugänglich zu machen, anstatt eine statische Variable. Auf diese Weise ist es aus architektonischer Sicht sinnvoll, und auch wenn Sie hypothetisch Farbschemata ändern möchten, selbst während der Ausführung, wären dies nur ein oder zwei Methoden auf dem AppController

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

    – Bis

    9. April 2012 um 17:19 Uhr

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

    – Sulthan

    9. April 2012 um 18:05 Uhr

1375470cookie-checkObjective C definiert UIColor-Konstanten

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy