7

I have a constants.m file that is a centralized collection of many program constants. To set a color, I do this:

@implementation UIColor (UIColor_Constants) 

+(UIColor *) defaultResultTableBackgroundColor{
    //return [[UIColor colorWithRed:0.6f green:0.004f blue:0.0f alpha:1.0f] retain];
    return [[UIColor colorWithRed:0.1f green:0.004f blue:0.3f alpha:0.3f] retain];
}

+(UIColor *) defaultResultHeaderBackgroundColor{
    return [[UIColor clearColor] retain];
}

@end

and in the constants.h I have

@interface UIColor (UIColor_Constants) 

+(UIColor *) defaultResultTableBackgroundColor;
+(UIColor *) defaultResultHeaderBackgroundColor;

@end

and then just use [UIColor defaultResultTableBackgroundColor] where I want to refer to this constant.

I would like to have some other UIColor and UIFont constants, and, while this works, it seems to be more complicated than it needs to be. Is there an easier way to do this?

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
Jim
  • 5,940
  • 9
  • 44
  • 91

5 Answers5

10

I use a constants file for the same purpose. Rather than setting up a whole interface and implementation file, I create the constants file as just the header (.h) file. Then, I define the colors I want to use, such as:

#define globalColor [UIColor colorWithRed:0.1f green:0.004f blue:0.3f alpha:0.3f]

Then, any time you use globalColor it's just like typing in the defined code.

superjessi
  • 1,790
  • 10
  • 17
  • 1
    This is not a constant. It's a macro; the compiler essentially uses this bit of code to replace all instances of 'globalColor' in your code. Functionally it's very different from a constant; practically, it's the same. – emma ray Dec 10 '14 at 22:16
  • How you use this global color in your application – Chandni Jul 10 '18 at 08:24
6

Here's a great read that explains constants in Objective C:

What is the best way to create constants in Objective-C

Short answer: You're handling this the best way possible.

Macros are not recommended. As some have mentioned, you could #define a macro to handle your colors. That's essentially telling the preprocessor to run find-and-replace on your code. There's a number of downsides to this approach, including scope and type. Apple explicitly recommends against these types of 'constants": https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html

It's also possible to create a constant:

(in your header, file scope)

extern UIColor *  const COLOR_LIGHT_BLUE;

(in your implementation, file scope)

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

You could, of course, #import this header in your prefix header to save even more typing. Ultimately, though, it's not much of an improvement over what you're already doing.

Community
  • 1
  • 1
emma ray
  • 13,336
  • 1
  • 24
  • 50
  • Answering this question has sent me on a quest to learn more about c const. You can (hopefully) get details here: http://stackoverflow.com/questions/27413196/how-is-static-const-different-from-extern-const – emma ray Dec 11 '14 at 00:09
6

I actually like this way too. One question: why do you retain the uicolor? This is very dangerous. It's very likely to make a mistake and to create a memory leak.

lbrndnr
  • 3,361
  • 2
  • 24
  • 34
  • 2
    Retaining the UIColor instance would be correct if he were storing it in a static variable so as to reuse it. As it is, you're right: Retaining it and then just returning it is incorrect. – Peter Hosey Aug 20 '11 at 02:17
2

You create a constant header file which contains all your colors and/or fonts like that:

// Define a convenient macro for example
#define HEXCOLOR(c) [UIColor colorWithRed:((c>>16)&0xFF)/255.0 \
                                    green:((c>>8)&0xFF)/255.0 \
                                     blue:c&0xFF/255.0 \
                                    alpha:0xFF/255.0]

// Then define your constants
#define DefaultResultTableBackgroundColor HEXCOLOR(0x151515)
// etc.
Yannick Loriot
  • 7,107
  • 2
  • 33
  • 56
  • 1
    Very nice. All I did for my purposes was remove the semicolons from the ends and I had to change c&0xFF to (c&0xFF) to fix a compile error. That way I can do borderColor = [DarkBlue CGColor]; Where DarkBlue is the HEXCOLOR define.. with semicolons that didn't work. – eselk Oct 03 '12 at 16:48
  • 1
    @eselk, there is no need to put semicolons after #define statement: #define HEXCOLOR(c) [UIColor colorWithRed:((c>>16)&0xFF)/255.0 \ green:((c>>8)&0xFF)/255.0 \ blue:c&0xFF/255.0 \ alpha:0xFF/255.0] If u make in such way, u will be able to use [DarkBlue CGColor] and DarkBlue.CGColor – Dennis Pashkov Sep 18 '14 at 13:55
  • 1
    This isn't really a constant, the UIColor will be recreated for each and every time it's accessed. – Maciej Swic Dec 10 '14 at 10:01
  • That's not a constant, and I'm sure there are many valid reasons to *not* use macros in place of constants. – emma ray Dec 10 '14 at 22:03
0

Answer is very simple. It can be used for NSArray and NSDictionary etc.

//Font
static UIFont *titleFont() {
    static UIFont *font = nil;
    if (!font) {
        font = [UIFont systemFontOfSize:25 weight:UIFontWeightHeavy];
    }
    return font;
}

//Color
static UIColor *prettyPurpleColor() {
    static UIColor *color = nil;
    if (!color) {
        color = [[UIColor purpleColor] colorWithAlphaComponent:0.35];
    }
    return color;
}
WINSergey
  • 1,977
  • 27
  • 39