如何定义UIColor的常量值?

63

我想做类似于这样的事情,但我无法得到合作的语法。

static const UIColor *colorNavbar = [UIColor colorWithRed: 197.0/255.0 green: 169.0/255.0 blue: 140.0/255.0 alpha: 1.0];

我想我可以定义宏,但它们很丑。


是的,在这种情况下,更具体地说是Objective-C语言 - 但它是在iPhone上。 - mobibob
在Objective-C++中,可以使用static UIColor *const color = ....。只需将扩展名更改为*.mm即可。 - Aleks N.
9个回答

126

我喜欢使用类别(category)来为类增加新方法,针对这种情况非常有效。以下是我今天刚写的一段代码摘录:

@implementation UIColor (Extensions)

+ (UIColor *)colorWithHueDegrees:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness {
    return [UIColor colorWithHue:(hue/360) saturation:saturation brightness:brightness alpha:1.0];
}

+ (UIColor *)aquaColor {
    return [UIColor colorWithHueDegrees:210 saturation:1.0 brightness:1.0];
}

+ (UIColor *)paleYellowColor {
    return [UIColor colorWithHueDegrees:60 saturation:0.2 brightness:1.0];
}

@end

现在我可以在代码中做这样的事情:

self.view.backgroundColor = highlight? [UIColor paleYellowColor] : [UIColor whitecolor];

我的自定义颜色可以与系统定义的颜色完美地融合在一起。

(顺便提一句,随着我对颜色的关注度越来越高,我开始更多地从HSB角度思考,而不是RGB。)

关于预计算值的更新: 我的直觉是这样做不值得。但如果你真的想要,你可以用静态变量来缓存这些值:

+ (UIColor *)paleYellowColor {
    static UIColor *color = nil;
    if (!color) color = [UIColor colorWithHueDegrees:60 saturation:0.2 brightness:1.0];
    return color;
}

你也可以使用宏来进行记忆化。


我喜欢这种方法。它在定义和使用中实现了我所寻找的组织。我以前不熟悉(Extensions),我需要阅读一下,因为它可能适用于我正在使用的其他类。最后,(可能有点跑题),是否有HSB 'picker'工具,就像有RBG picker一样。我喜欢IB,但我发现将互补颜色放在一起很有帮助,因为通常我想要多个颜色。 - mobibob
哦,是的,但我试图解决的一个问题是获取预计算值。我不想每次引用颜色时执行三个除法。 - mobibob
1
关于颜色选择:我不是专家。我使用Interface Builder中的颜色选择器。它有一个颜色轮,可以滑动RGB或HSB的滑块,还有一个蜡笔盒。我很喜欢它。 - jasoncrawford
3
将上述代码保存到名为UIColor_MyColors.m的文件中,然后创建UIColor_MyColors.h文件,其中包含以下内容:#import @interface UIColor () + (UIColor *)aquaColor; @end要使用它,请导入UIColor_MyColors.h文件:#import "UIColor_MyColors.h"并像这样引用颜色:[self.view setBackgroundColor:[UIColor aquaColor]]; - drpawelo
如果您习惯使用RGB(例如(255,255,255)),则可以改用Web将RGB转换为色相值(http://serennu.com/colour/hsltorgb.php),或者将此函数添加到上面的代码中:+ (UIColor *)colorWithWebRed:(CGFloat)red Green:(CGFloat)green Blue:(CGFloat)blue { return [UIColor colorWithRed:red/255 green:green/255 blue:blue/255 alpha:1.0]; }并像这样使用它:+ (UIColor *)aquaColor { return [UIColor colorWithWebRed:59 Green:89 Blue:152]; } - drpawelo

35

我通常为每个项目创建一个UIColor类别:

@interface UIColor (ProjectName)

+(UIColor *) colorForSomeTable;
+(UIColor *) colorForSomeControl;
+(UIColor *) colorForSomeText;

@end

使用实现中的常量:

@implementation UIColor (ProjectName)

+(UIColor *) colorForSomeTable { return [UIColor colorWithRed:...]; }

@end

我也会根据需要对UIFont和UIImage执行相同的操作。


4
非常好!我的附加问题是,这段代码应该放在哪里?我有Constants.h/Constants.m文件(在我的预编译标头中),我只想“声明”一个常量颜色......我不喜欢把这种代码放在那里...你会把它放在哪里? - Andy M
在我看来,这是正确的方式。 - Johan Karlsson

11

为了进一步说明jasoncrawford的回答(我会在评论中加入,但你不能在评论中格式化代码),如果你想要预先计算这些值(或者只计算一次)。

+ (UIColor *)paleYellowColor
{
    static UIColor* paleYellow = nil;
    if (paleYellow == nil)
    {
        paleYellow = [UIColor colorWithHueDegrees:60 saturation:0.2 brightness:1.0];
    }
    return paleYellow;
}
你原本的想法不能正常工作的原因是,编译器只能在函数外使用初始化器,而不能在普通代码中使用。你可以通过initialize方法实现类似于所需功能的效果。
static UIColor* colorNavBar = nil;

+(void) initialize
{
    if (colorNavBar != nil)
    {
        colorNavBar = ....
    }
}

注意,您原始定义中的const限定词是多余的,因为UIColor本身是不可变的。


谢谢这些好的技巧和方法。我可能会在其他更具体的应用程序设计任务中遵循这种模式。我正在使用Jason第一篇帖子中建议的类别/分类。这样可以优雅地定义各种颜色的主题类。 - mobibob
哦,关于不可变的常量 - 是的,我明白了!谢谢你指出来。 - mobibob

10
你可以像这样“定义”一个类似的常量:

您可以像此示例一样“定义”类似的常量:

#define FAV_COLOR [UIColor colorWithRed:24/255.0f green:89/255.0f blue:36/255.0f alpha:0.9]

你可以像使用常量一样,用名称来调用它:FAV_COLOR

希望这可以帮到你。


kasperfn 这与 intorpedro 的答案相同。我更喜欢避免使用宏,因此我更青睐于使用类别的解决方案,因为它是更好的面向对象编程语言的使用方式。 - mobibob
使用宏定义常量是一件不好的事情。 - Iulian Onofrei
@IulianOnofrei 有什么具体原因吗?为什么宏不好?有任何性能问题吗?请简要说明。 - Ganpat

8
你可以这样做:
#define backgroundColorApp [UIColor colorWithRed: 197.0/255.0 green: 169.0/255.0 blue: 140.0/255.0 alpha: 1.0]

2
当更安全的类型或编译器安全的替代方案可用时,我会避免使用宏解决方案。您可能会注意到在我的原始描述中,我承认存在“宏”解决方案,但它们很“丑陋”。在这种情况下,丑陋的原因是因为可以使用语言的类别特性来实现一个干净的解决方案。 - mobibob

6

在Swift中,定义一个扩展:

extension UIColor {
    
   class func XXXWhiteColor() -> UIColor {
        return UIColor(red: 256, green: 256, blue: 256, alpha: 1.0)
    }
 
    class func XXXGreenColor() -> UIColor {
        return UIColor(red: 73/255.0, green: 212/255.0, blue: 86/255.0, alpha: 1.0)
    }
}

使用方法:

label.background = UIColor.XXXWhiteColor()

4
#define textColorApp [UIColor colorWithRed: 197.0/255.0 green: 169.0/255.0 blue: 140.0/255.0 alpha: 1.0]

myLabel.textColor=textColorApp;

抱歉 - 仍然是宏解决方案。我更喜欢类别解决方案并扩展UIColor类。 - mobibob

1

只需在您的常量文件中定义以下宏,并传递仅RGB值,然后您可以在任何地方使用

#define RGBCOLOR(r,g,b)[UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]

使用方法:

[lblCount setTextColor:RGBCOLOR(236, 43, 92)];

谢谢 - 但我仍然更喜欢避免使用宏。我更喜欢类别答案,因为它是更好的面向对象语言使用方式。 - mobibob
我也做了同样的事情,但在Objective-C中显示了预期的表达式错误。 - Chandni

0

我认为值得一提的另一个很棒的功能是颜色字面量,但它很少被讨论。它们不仅更易于阅读,而且编辑起来也要容易得多。在Swift中,

let color: UIColor = #colorLiteral(red: 0.9607843137, green: 0.4784313725, blue: 0.3215686275, alpha: 

将此语法粘贴到Xcode中,即可创建一个简单的颜色框。点击此处查看示例。

一旦您看到该框,就可以双击它以轻松编辑。同样,如果您有来自设计师的特定颜色十六进制值列表,您也可以在各种IB选项之间切换,包括RGB滑块


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接