This repository has been archived by the owner on Nov 27, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
TKThemeManager.m
209 lines (157 loc) · 6.51 KB
/
TKThemeManager.m
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
//
// TKThemeManager
//
// Created by Taras Kalapun on 6/12/12.
//
#import "TKThemeManager.h"
#import "IJContext.h"
#define UIColorFromRGBA(rgbValue, alphaValue) ([UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16)) / 255.0 \
green:((float)((rgbValue & 0xFF00) >> 8)) / 255.0 \
blue:((float)(rgbValue & 0xFF)) / 255.0 \
alpha:alphaValue])
#define UIColorFromRGB(rgbValue) (UIColorFromRGBA((rgbValue), 1.0))
#define IPAD ((__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200) && (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad))
#define IPHONE (!IPAD)
@interface NSDictionary (TKThemed)
- (id)TKObjectForKey:(id)aKey;
- (id)TKValueForKeyPath:(NSString *)keyPath;
@end
// TODO: static keys
@implementation TKThemeManager
injective_register_singleton(TKThemeManager)
@synthesize themeOptions = _themeOptions;
- (id)themedValueForPath:(NSString *)themePath
{
return [self.themeOptions TKValueForKeyPath:themePath];
}
- (void)loadFromBundleWithFileName:(NSString *)fileName
{
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:@"plist"];
self.themeOptions = [NSDictionary dictionaryWithContentsOfFile:path];
}
- (UIViewController *)rootViewControllerFromLayout
{
return [self viewControllerFromPropertyDictionary:[self themedValueForPath:@"layout"]];
}
- (UIViewController *)viewControllerFromPropertyDictionary:(NSDictionary *)propertyDict {
if (!propertyDict) return nil;
NSAssert([propertyDict isKindOfClass:[NSDictionary class]], @"Expected a dictionary where a %@ was found", NSStringFromClass([propertyDict class]));
UIViewController *controller = nil;
NSString *controllerName = [propertyDict TKObjectForKey:@"controller"];
NSAssert([controllerName isKindOfClass:[NSString class]], @"The controller name should be a string");
//Instantiate
NSString *nibName = [propertyDict TKObjectForKey:@"nibName"];
NSBundle *nibBundle = [NSBundle bundleWithPath:[propertyDict TKObjectForKey:@"nibBundle"]];
if (nibName) {
controller = [[NSClassFromString(controllerName) alloc] initWithNibName:nibName bundle:nibBundle];
}
else {
controller = [[NSClassFromString(controllerName) alloc] init];
}
NSAssert(controller != nil, @"The controller named %@ can not be created", controllerName);
NSAssert([controller isKindOfClass:[UIViewController class]], @"The controller %@ should be kind of UIViewController", controllerName);
//Properties
NSString *title = [propertyDict TKObjectForKey:@"title"];
if (title) {
controller.title = NSLocalizedString(title, nil);
}
//Subcontrollers
NSArray *subControllers = [propertyDict TKObjectForKey:@"subControllers"];
if (([controller respondsToSelector:@selector(setViewControllers:)]) && subControllers) {
NSAssert([subControllers isKindOfClass:[NSArray class]], @"Subcontrollers should be an array");
NSMutableArray *vcs = [NSMutableArray arrayWithCapacity:subControllers.count];
for (NSDictionary *subController in subControllers) {
UIViewController *vc = [self viewControllerFromPropertyDictionary:subController];
if (vc) {
[vcs addObject:vc];
}
}
[controller performSelector:@selector(setViewControllers:) withObject:vcs];
}
//Navigation bar
BOOL inNavigationController = [[propertyDict TKObjectForKey:@"inNavigationController"] boolValue];
if (inNavigationController) {
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:controller];
int barStyle = [[propertyDict TKObjectForKey:@"navBarStyle"] intValue];
nc.navigationBar.barStyle = barStyle;
controller = nc;
}
return controller;
}
@end
@implementation UIImage (TKThemed)
// WARNING: read comments!
+ (UIImage *)themedFor:(NSString *)themePath {
UIImage *img = nil;
// if we have '.' in path - route it to plist
// if not - get image directly
if ([themePath rangeOfString:@"."].location != NSNotFound) {
// Does contain the substring
NSString *imgName = themedValue(themePath);
img = [UIImage imageNamed:imgName];
if (!img) NSLog(@"[TKThemeManager] No Image %@ for %@", imgName, themePath);
} else {
img = [UIImage imageNamed:themePath];
if (!img) NSLog(@"[TKThemeManager] No Image %@", themePath);
}
return img;
}
@end
@implementation UIFont (TKThemed)
+ (UIFont *)themedFor:(NSString *)themePath {
NSString *fontData = themedValue(themePath);
NSArray *fa = [fontData componentsSeparatedByString:@":"];
NSString *fontName = [fa objectAtIndex:0];
CGFloat fontSize = [[fa objectAtIndex:1] floatValue];
if (fontSize == 0) {
fontSize = [UIFont systemFontSize];
}
if ([fontName isEqualToString:@""]) {
return [UIFont systemFontOfSize:fontSize];
}
if ([fontName isEqualToString:@"bold"] || [fontName isEqualToString:@"b"]) {
return [UIFont boldSystemFontOfSize:fontSize];
}
return [UIFont fontWithName:fontName size:fontSize];
}
@end
@implementation UIColor (TKThemed)
+ (UIColor *)themedFor:(NSString *)themePath {
NSString *hexString = [themedValue(themePath) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (!hexString) {
NSLog(@"[TKThemeManager] No Color for %@", themePath);
return nil;
}
NSScanner *scanner = [NSScanner scannerWithString:hexString];
unsigned hex;
BOOL success = [scanner scanHexInt:&hex];
if (!success) return nil;
if ([hexString length] <= 6)
return UIColorFromRGB(hex);
else {
unsigned color = (hex & 0xFFFFFF00) >> 8;
CGFloat alpha = 1.0 * (hex & 0xFF) / 255.0;
return UIColorFromRGBA(color, alpha);
}
}
@end
@implementation NSDictionary (TKThemed)
- (id)TKObjectForKey:(id)aKey {
//Check the value for the specific device
NSString *keyPathDevice = [aKey stringByAppendingString:(IPAD? @"~iPad" : @"~iPhone")];
id deviceValue = [self objectForKey:keyPathDevice];
if (deviceValue) {
return deviceValue;
}
return [self objectForKey:aKey];
}
- (id)TKValueForKeyPath:(NSString *)keyPath {
//Check the value for the specific device
NSString *keyPathDevice = [keyPath stringByAppendingString:(IPAD? @"~iPad" : @"~iPhone")];
id deviceValue = [self valueForKeyPath:keyPathDevice];
if (deviceValue) {
return deviceValue;
}
return [self valueForKeyPath:keyPath];
}
@end