2010-05-13 205 views
25

我有一个iPhone应用程序,其中包含一些自定义颜色的主题。由于这些颜色将为我的用户界面固定,因此我想定义要包含的类中的颜色(Constants.h和Constants.m)。我怎么做? (简单地定义它们是行不通的,因为UIColors是可变的,并且会导致错误 - Initalizer不是常量)。Objective C定义UIColor常量

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

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

谢谢!

回答

42

UIColor不可变。我通常用颜色,字体和图像来做这件事。您可以轻松修改它以使用单例或具有静态初始化器。

@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为第一句话 - 初始化是什么不是常数,而不是实例。对于所有的意图和目的,UIColor可以(或者明天可能)包含未暴露给用户的内部状态变量,使它们看起来对我们来说是恒定的,然而在Obj-C中没有任何东西强迫它。因此编译器无法使用静态初始化器,因为[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]是一个方法调用,因此不能将结果放在文本段中,这是在编译时创建的。 – 2010-05-13 04:28:40

+5

可变意味着您可以更改实例。不可变意味着你不能改变实例。常量意味着该实例无法更改。 UIColor不可变,也不是恒定的。只有CFString/NSString具有真正的常量实例,因为它们作为编译器语言的一部分专门处理。 – drawnonward 2010-05-13 15:32:45

+1

那么你如何在你的代码中引用这种颜色? – scientiffic 2015-08-21 20:53:11

0

人们常常把全局常量为单一对象 - 或drawnonward注意,你可以让他们通过一些类中的一个方法访问。

-1

使用AppController可以全局访问颜色,而不是静态变量。这样,它是有道理的,从架构的角度来看,也如果你想改变假设的配色方案,即使同时运行,这也只是在AppController中

+0

AppController - 我想你指的是UIApplication委托? – Till 2012-04-09 17:19:22

+0

在大多数应用程序中,在运行时更改颜色将会变得更大。使用与其无关的代码污染应用程序代理的好方法。 – Sulthan 2012-04-09 18:05:15

13

的方法或两个在你的.h另一种选择

你可以做

extern UIColor * const COLOR_LIGHT_BLUE; 

在.mm你可以做

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

什么是这种狡猾的C + +动态常量? ;)+1 – Greg 2012-04-16 13:27:38

+0

我很感兴趣,为什么这也可能。 – 2013-07-09 03:49:55

+0

这是可能的,因为'T * const'是一个指向常规对象的常量指针(不能修改指向这个指针的位置),而不是const T *,它是一个指向常量对象的指针(不能通过这样的指针修改对象)。 – 2013-08-02 04:31:57

30

为了简单起见我这样做:

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

不要忘记忽略';'所以你可以使用它作为一个正常的表达。

我不知道如果有什么技术上的错误用这种方法,但它工作正常,并避免编译时间常数初始化错误 - 该代码是有效卡在任何地方你把“myColor”,所以它不直到你真正使用它才会被编译。

+0

有趣的做法!我会感兴趣为什么';'可以被排除在外?这是怎么回事? – brainray 2013-12-29 18:57:15

+2

这是一个预处理宏。有效地,'myColor'在代码出现在代码中时会被替换为完整的'[UIColor colorWith ...'代码行,在它编译之前。你忽略了';'在宏中,您可以使用如下代码:'UIColor * color = myColor;'而不是'UIColor * color = myColor',它看起来不像普通的代码行(将分号放在任何代码行的结尾)。它可以被忽略,因为预处理器宏在使用时被评估,因此只要你在实际的代码中放置一个分号,你就没问题。 – 2013-12-30 20:26:25

+2

但是,每次使用此宏时,这是否不会创建此颜色的新实例?考虑将它放在1000次迭代的for循环中,并将其作为背景颜色分配给视图。这不是很有效吗? – Majster 2014-01-05 17:20:26

3

如果你正在寻找一个快速和肮脏一个没有扩展名一起去clang

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

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

} 
+0

真棒代码,谢谢! – Genevios 2015-04-08 16:27:34

0

这里的另一种方式:

页眉:

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

COLORS_EXTERN UIColor *aGlobalColor; 

实现:

#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 

这有点破解,但你不需要重新定义实现中的颜色,并且可以在没有方法调用的情况下访问颜色。