Is Macro Better Than UIColor for Setting RGB Color?

19,672

Solution 1

A middle ground might be your best option. You could define either a regular C or objective-C function to do what your macro is doing now:

// As a C function:
UIColor* UIColorFromRGB(NSInteger rgbValue) {
    return [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0
                           green:((float)((rgbValue & 0xFF00) >> 8))/255.0
                            blue:((float)(rgbValue & 0xFF))/255.0
                           alpha:1.0];
}

// As an Objective-C function:
- (UIColor *)UIColorFromRGB:(NSInteger)rgbValue {
return [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0
                       green:((float)((rgbValue & 0xFF00) >> 8))/255.0
                        blue:((float)(rgbValue & 0xFF))/255.0
                       alpha:1.0];
}

If you decide to stick with the macro, though, you should put parentheses around rgbValue wherever it appears. If I decide to call your macro with:

UIColorFromRGB(0xFF0000 + 0x00CC00 + 0x000099);

you may run into trouble.

The last bit of code is certainly the most readable, but probably the least portable - you can't call it simply from anywhere in your program.

All in all, I'd suggest refactoring your macro into a function and leaving it at that.

Solution 2

or create a separate category, so you only need to import one .h file:

@interface UIColor (util)
+ (UIColor *) colorWithHexString:(NSString *)hex;
+ (UIColor *) colorWithHexValue: (NSInteger) hex;
@end

and

#import "UIColor-util.h"

@implementation UIColor (util)

// Create a color using a string with a webcolor
// ex. [UIColor colorWithHexString:@"#03047F"]
+ (UIColor *) colorWithHexString:(NSString *)hexstr {
    NSScanner *scanner;
    unsigned int rgbval;

    scanner = [NSScanner scannerWithString: hexstr];
    [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"#"]];
    [scanner scanHexInt: &rgbval];

    return [UIColor colorWithHexValue: rgbval];
}

// Create a color using a hex RGB value
// ex. [UIColor colorWithHexValue: 0x03047F]
+ (UIColor *) colorWithHexValue: (NSInteger) rgbValue {
    return [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0
                           green:((float)((rgbValue & 0xFF00) >> 8))/255.0
                            blue:((float)(rgbValue & 0xFF))/255.0
                           alpha:1.0];

}


@end

Solution 3

How about creating your own:

#define RGB(r, g, b) \
    [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define RGBA(r, g, b, a) \
    [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)]

Then use it:

cell.textColor = RGB(0x66, 0x33, 0x33);

Seems simple enough to use, uses hex values for colors and without needing additional calculation overhead.

Solution 4

I typically recommend functions rather than complex #defines. If inlining has a real benefit, the compiler will generally do it for you. #defines make debugging difficult, particularly when they're complex (and this one is).

But there's nothing wrong with using a function here. The only nitpick I'd say is that you should be using CGFloat rather than float, but there's nothing wrong with the hex notation if it's more comfortable for you. If you have a lot of these, I can see where using Web color notation may be convenient. But avoid macros.

Share:
19,672
Rahul Vyas
Author by

Rahul Vyas

Sr. iOS Developer, Gamer

Updated on July 31, 2022

Comments

  • Rahul Vyas
    Rahul Vyas almost 2 years

    I have this macro in my header file:

    #define UIColorFromRGB(rgbValue) \
            [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
                            green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
                             blue:((float)(rgbValue & 0xFF))/255.0 \
                            alpha:1.0]

    And I am using this as something like this in my .m file:

    cell.textColor = UIColorFromRGB(0x663333);

    So I want to ask everyone is this better or should I use this approach:

    cell.textColor = [UIColor colorWithRed:66/255.0
                                     green:33/255.0
                                      blue:33/255.0
                                     alpha:1.0];

    Which one is the better approach?

  • Rahul Vyas
    Rahul Vyas almost 15 years
    but how do i pass this web safe colour value in colorwithrgb method 33CC00
  • Rahul Vyas
    Rahul Vyas almost 15 years
    but how do i pass this web safe colour value 33CC00 in colorwithrgb method
  • Rob Napier
    Rob Napier almost 15 years
    Precisely as with the macro, by passing "0x33CC00". That's a legal integer, so you can pass it as a parameter.
  • Rahul Vyas
    Rahul Vyas almost 15 years
    how do i pass that in [UIColor colorWithRed:66/255.0 green:33/255.0 blue:33/255.0 alpha:1.0]; this method
  • Marius
    Marius over 8 years
    The parenthesis was actually pretty important, leaving it out would render values like RGB(100+100, 255, 255) incorrectly due to macro replacement side-effects. ( Red rould have the value: 100 + 100/255.0 = 100.4 )