Class Methods and Typedef Enums
This is a nifty little “pattern” for collecting reusable elements, color, labels, settings etc. that is standard through out your program. I do use Interface Builder, but I prefer reuse approach of code.
When a projects design has been agreed upon and the basic things are laid out: font, size, color theme etc. I usually build myself an ISInterfaceElements class. This class contains a few Class Methods called getColor:(ColorType) type and getLabel:(LabelType) type. Our Proof-of-Concept Class will contain 3 different colors: BackgroundColor, ForegroundColor and TextColor. It will also contain 3 types of labels, a HeadlineLabel, TextLabel and a DetailLabel. These six components will get you pretty far in describing the text and color of an iPhone App.
How to do it “manually”.
If I were to build a UILabel, using nothing but code, and make it adhere to the design mentioned above it would probably go a bit like this:
1
2
3
4
5
6
7
8
9
10 UILabel *label = [[UILabel alloc] init];
[label setFrame:CGRectMake(0.0f, 0.0f, 320.0f, 20.0f)];
[label setFont:[UIFont fontWithName:@"Helvetica" size:14]];
[label setTextAlignment:UITextAlignmentCenter];
UIColor *textColor = [UIColor colorWithRed:0.2f green:0.5f blue:0.3f alpha:1.0f];
[label setTextColor:textColor];
[label setShadowColor:[UIColor darkGrayColor]];
[label setShadowOffset:CGSizeMake(0.0f, 1.0f)];
If you do stuff like this manually and scattered around your program you will at some point encounter the “Let’s change the font and color of the app!” witch will leave you with a couple of hours of “Sherlock Holmes copy-paste”, as I like to call it.
Instead we will try to gather common functionality in a single class so that any change made here will propagate outwards to all the parts of the code.
We will use the approach that Apple often uses in their frameworks, e.g. when initializing a UIButton you could do it like this:
1 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
The way to go about this is to write a Class that has Class Methods for getting a UILabel and UIColor back, and instead of giving them ID’s like 0034, 1234 etc. we write a typedef enum with nice, easy-to-remember names like UIButtonTypeCustom above. This will make sure code completion and compiler checking will work with you instead of against you.
The Class:
As I wrote at the beginning our class will have 3 label and 3 colors, so we start out by writing typedef enums for these elements and we define a (UILabel*) getLabel:(LabelType) type and (UIColor*)getColor:(ColorType) type method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 //
// ISInterfaceElements.h
// BlogPostCode
//
// Created by RickiG on 6/21/10.
// Copyright 2010 www.rickigregersen.com. Use as you please:).
//
#import <Foundation/Foundation.h>
typedef enum {
BackgroundColor = 0, //This will give the BackgroundColor the ID 0 and ForeGroundColor the ID 1 etc.
ForegroundColor, //it is not needed, if left out it will default to 0,1,2...
TextColor,
} ColorType;
typedef enum {
HeadlineLabel = 3, //This will give the HeadlineLabel the ID 3, the TextLabel 4 etc.
TextLabel, //use this only if the enums can not have the same value, in our case
DetailLabel, //they are not needed, but shown to illustrate that enums just corresponds to integers
} LabelType;
@interface ISInterfaceElements : NSObject {
}
+ (UIColor*) getColor:(ColorType) type;
+ (UILabel*) getLabel:(LabelType) type;
@end
Now we implement these two methods. The logic of determining which kind of Color of Label is returned is done with a switch case (as the enums are integers):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 //
// ISInterfaceElements.m
// BlogPostCode
//
// Created by RickiG on 6/21/10.
// Copyright 2010 www.rickigregersen.com. Use as you please:).
//
#import "ISInterfaceElements.h"
#define APP_FONT @"HelveticaNeue" //Defined once so that it is simple to change the font of the app
#define APP_FONT_BOLD @"HelveticaNeue-Bold"
@implementation ISInterfaceElements
+ (UIColor*) getColor:(ColorType) type {
int value; //We deal with the Color in terms of Hex, this is what a designer will often return.
switch (type) {
case BackgroundColor:
value = 0x2d3c3f;
break;
case ForegroundColor:
value = 0x627376;
break;
case TextColor:
value = 0xDDDDDD;
break;
default:
value = 0x000000;
break;
}
int r, g, b;
b = value & 0x0000FF;
g = ((value & 0x00FF00) >> 8);
r = ((value & 0xFF0000) >> 16);
return [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:1.0f];
}
+ (UILabel*) getLabel:(LabelType) type {
UILabel *label = [[[UILabel alloc] init] autorelease];
[label setBackgroundColor:[UIColor clearColor]];
switch (type) {
case HeadlineLabel:
[label setFont:[UIFont fontWithName:APP_FONT_BOLD size:14]];
[label setTextColor:[self getColor:TextColor]];
label.shadowColor = [UIColor darkGrayColor];
label.shadowOffset = CGSizeMake(0.0, 1.0);
break;
case TextLabel:
[label setFont:[UIFont fontWithName:APP_FONT size:12]];
[label setTextColor:[UIColor whiteColor]];
label.shadowColor = [UIColor blackColor];
label.shadowOffset = CGSizeMake(0.0, 1.0);
break;
case DetailLabel:
[label setFont:[UIFont fontWithName:APP_FONT size:10]];
[label setTextColor:[UIColor darkGrayColor]];
[label setTextAlignment:UITextAlignmentRight];
break;
default:
break;
}
return label;
}
@end
Using the ISInterfaceElements Class:
Now that the class is set up it is really simple to obtain a UILabel or UIColor in a way that 1) does not clutter up your code with repeating setup-code 2) makes your design consistent, fonts and colors are easily changed in one location 3) follows the approach you know from Apples frameworks.
Make sure to import the ISInterfaceElements.h header then do the highlighted part below:
1
2
3
4
5
6
7
8
9
10
11 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch
UILabel *headline = [ISInterfaceElements getLabel:HeadlineLabel];
[headline setText:@"Hello, World"];
[window addSubview:headline];
[window makeKeyAndVisible];
return YES;
}
No Comments on "Class Methods and Typedef Enums"