-
Notifications
You must be signed in to change notification settings - Fork 4
/
PSStyleSheet.m
299 lines (242 loc) · 11.8 KB
/
PSStyleSheet.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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
//
// PSStyleSheet.m
// PSKit
//
// Created by Peter Shih on 8/10/11.
// Copyright (c) 2011 Peter Shih.. All rights reserved.
//
#import "PSStyleSheet.h"
static PSStyleSheet *__defaultStyleSheet = nil;
@interface UIColor (PSStyleSheet)
+ (UIColor *)colorWithRGBHex:(UInt32)hex;
+ (UIColor *)colorWithHexString:(NSString *)stringToConvert;
@end
@implementation UIColor (PSStyleSheet)
+ (UIColor *)colorWithRGBHex:(UInt32)hex {
int r = (hex >> 16) & 0xFF;
int g = (hex >> 8) & 0xFF;
int b = (hex) & 0xFF;
return [UIColor colorWithRed:r / 255.0f
green:g / 255.0f
blue:b / 255.0f
alpha:1.0f];
}
// Returns a UIColor by scanning the string for a hex number and passing that to +[UIColor colorWithRGBHex:]
// Skips any leading whitespace and ignores any trailing characters
+ (UIColor *)colorWithHexString:(NSString *)stringToConvert {
NSScanner *scanner = [NSScanner scannerWithString:stringToConvert];
unsigned hexNum;
if (![scanner scanHexInt:&hexNum]) return nil;
return [UIColor colorWithRGBHex:hexNum];
}
@end
@interface UILabel (PSStyleSheet_Private)
+ (CGSize)sizeForText:(NSString*)text width:(CGFloat)width font:(UIFont*)font numberOfLines:(NSInteger)numberOfLines lineBreakMode:(UILineBreakMode)lineBreakMode;
@end
@implementation UILabel (PSStyleSheet_Private)
+ (CGSize)sizeForText:(NSString*)text width:(CGFloat)width font:(UIFont*)font numberOfLines:(NSInteger)numberOfLines lineBreakMode:(UILineBreakMode)lineBreakMode {
if (numberOfLines == 0) numberOfLines = INT_MAX;
CGFloat lineHeight = [@"A" sizeWithFont:font].height;
return [text sizeWithFont:font constrainedToSize:CGSizeMake(width, numberOfLines * lineHeight) lineBreakMode:lineBreakMode];
}
@end
@implementation UILabel (PSStyleSheet)
+ (UILabel *)labelWithStyle:(NSString *)style {
UILabel *l = [[UILabel alloc] initWithFrame:CGRectZero];
[PSStyleSheet applyStyle:style forLabel:l];
return l;
}
@end
@interface PSStyleSheet ()
+ (PSStyleSheet *)defaultStyleSheet;
@property (nonatomic, strong) NSMutableDictionary *styles;
@end
@implementation PSStyleSheet
+ (PSStyleSheet *)defaultStyleSheet {
if (!__defaultStyleSheet) {
__defaultStyleSheet = [[self alloc] init];
}
// Make sure we have a style sheet set
if (!__defaultStyleSheet.styles) return nil;
return __defaultStyleSheet;
}
- (id)init {
self = [super init];
if (self) {
self.styles = [NSMutableDictionary dictionary];
}
return self;
}
#pragma mark - Config
+ (void)setStyleSheet:(NSString *)styleSheet {
NSString *styleSheetPath = [[NSBundle mainBundle] pathForResource:styleSheet ofType:@"plist"];
assert(styleSheetPath != nil);
NSMutableDictionary *styleSheetDict = [NSMutableDictionary dictionaryWithContentsOfFile:styleSheetPath];
assert(styleSheetDict != nil);
[[[self class] defaultStyleSheet] setStyles:styleSheetDict];
}
+ (NSDictionary *)styleDictForStyle:(NSString *)style {
// Make sure there is a style sheet loaded
NSAssert([[self class] defaultStyleSheet].styles, @"no style sheet");
return [[[self class] defaultStyleSheet].styles objectForKey:style];
}
#pragma mark - Applying Styles
+ (void)applyStyle:(NSString *)style forLabel:(UILabel *)label {
// Determine if style exists, if it doesn't, throw an assertion
NSAssert1([[self class] styleDictForStyle:style], @"style: %@ does not exist", style);
label.font = [PSStyleSheet fontForStyle:style];
label.minimumFontSize = [PSStyleSheet minimumFontSizeForStyle:style];
label.textColor = [PSStyleSheet textColorForStyle:style];
label.highlightedTextColor = [PSStyleSheet highlightedTextColorForStyle:style];
label.shadowColor = [PSStyleSheet shadowColorForStyle:style];
label.shadowOffset = [PSStyleSheet shadowOffsetForStyle:style];
label.textAlignment = [PSStyleSheet textAlignmentForStyle:style];
label.backgroundColor = [PSStyleSheet backgroundColorForStyle:style];
label.numberOfLines = [PSStyleSheet numberOfLinesForStyle:style];
label.lineBreakMode = [PSStyleSheet lineBreakModeForStyle:style];
label.adjustsFontSizeToFitWidth = [PSStyleSheet adjustsFontSizeToFitWidthForStyle:style];
}
+ (void)applyStyle:(NSString *)style forButton:(UIButton *)button {
// Determine if style exists, if it doesn't, throw an assertion
NSAssert1([[self class] styleDictForStyle:style], @"style: %@ does not exist", style);
[button setTitleColor:[PSStyleSheet textColorForStyle:style] forState:UIControlStateNormal];
[button setTitleColor:[PSStyleSheet highlightedTextColorForStyle:style] forState:UIControlStateHighlighted];
[button setTitleShadowColor:[PSStyleSheet shadowColorForStyle:style] forState:UIControlStateNormal];
button.titleLabel.font = [PSStyleSheet fontForStyle:style];
button.titleLabel.minimumFontSize = [PSStyleSheet minimumFontSizeForStyle:style];
button.titleLabel.adjustsFontSizeToFitWidth = [PSStyleSheet adjustsFontSizeToFitWidthForStyle:style];
button.titleLabel.shadowOffset = [PSStyleSheet shadowOffsetForStyle:style];
button.contentHorizontalAlignment = [PSStyleSheet horizontalAlignmentForStyle:style];
}
+ (void)applyStyle:(NSString *)style forTextField:(UITextField *)textField {
// Determine if style exists, if it doesn't, throw an assertion
NSAssert1([[self class] styleDictForStyle:style], @"style: %@ does not exist", style);
[textField setTextColor:[PSStyleSheet textColorForStyle:style]];
[textField setFont:[PSStyleSheet fontForStyle:style]];
[textField setTextAlignment:[PSStyleSheet textAlignmentForStyle:style]];
}
#pragma mark - Size calculation
+ (CGSize)sizeForText:(NSString *)text width:(CGFloat)width style:(NSString *)style {
CGSize size = [UILabel sizeForText:text width:width font:[[self class] fontForStyle:style] numberOfLines:[[self class] numberOfLinesForStyle:style] lineBreakMode:[[self class] lineBreakModeForStyle:style]];
return size;
}
#pragma mark - Fonts
+ (UIFont *)fontForStyle:(NSString *)style {
UIFont *font = nil;
if ([[[self class] styleDictForStyle:style] objectForKey:@"fontName"] && [[[self class] styleDictForStyle:style] objectForKey:@"fontSize"]) {
font = [UIFont fontWithName:[[[self class] styleDictForStyle:style] objectForKey:@"fontName"] size:[[[[self class] styleDictForStyle:style] objectForKey:@"fontSize"] integerValue]];
}
return font;
}
+ (CGFloat)minimumFontSizeForStyle:(NSString *)style {
CGFloat minimumFontSize = 0.0;
if ([[[self class] styleDictForStyle:style] objectForKey:@"minimumFontSize"]) {
minimumFontSize = [[[[self class] styleDictForStyle:style] objectForKey:@"minimumFontSize"] floatValue];
}
return minimumFontSize;
}
#pragma mark - Colors
+ (UIColor *)textColorForStyle:(NSString *)style {
UIColor *color = nil;
if ([[[self class] styleDictForStyle:style] objectForKey:@"textColor"]) {
color = [UIColor colorWithHexString:[[[self class] styleDictForStyle:style] objectForKey:@"textColor"]];
}
return color;
}
+ (UIColor *)highlightedTextColorForStyle:(NSString *)style {
UIColor *color = nil;
if ([[[self class] styleDictForStyle:style] objectForKey:@"highlightedTextColor"]) {
color = [UIColor colorWithHexString:[[[self class] styleDictForStyle:style] objectForKey:@"highlightedTextColor"]];
}
return color;
}
+ (UIColor *)shadowColorForStyle:(NSString *)style {
UIColor *color = nil;
if ([[[self class] styleDictForStyle:style] objectForKey:@"shadowColor"]) {
color = [UIColor colorWithHexString:[[[self class] styleDictForStyle:style] objectForKey:@"shadowColor"]];
}
return color;
}
+ (UIColor *)backgroundColorForStyle:(NSString *)style {
UIColor *color = nil;
if ([[[self class] styleDictForStyle:style] objectForKey:@"backgroundColor"]) {
color = [UIColor colorWithHexString:[[[self class] styleDictForStyle:style] objectForKey:@"backgroundColor"]];
} else {
color = [UIColor clearColor];
}
return color;
}
#pragma mark - Offsets
+ (CGSize)shadowOffsetForStyle:(NSString *)style {
CGSize offset = CGSizeZero;
if ([[[self class] styleDictForStyle:style] objectForKey:@"shadowOffset"]) {
offset = CGSizeFromString([[[self class] styleDictForStyle:style] objectForKey:@"shadowOffset"]);
}
return offset;
}
#pragma mark - Text Alignment
+ (UITextAlignment)textAlignmentForStyle:(NSString *)style {
// Defaults to UITextAlignmentLeft if undefined
if ([[[self class] styleDictForStyle:style] objectForKey:@"textAlignment"]) {
NSString *textAlignmentString = [[[self class] styleDictForStyle:style] objectForKey:@"textAlignment"];
if ([textAlignmentString isEqualToString:@"center"]) {
return UITextAlignmentCenter;
} else if ([textAlignmentString isEqualToString:@"right"]) {
return UITextAlignmentRight;
} else return UITextAlignmentLeft;
} else {
return UITextAlignmentLeft;
}
}
+ (UIControlContentHorizontalAlignment)horizontalAlignmentForStyle:(NSString *)style {
// Defaults to CENTER if undefined
if ([[[self class] styleDictForStyle:style] objectForKey:@"textAlignment"]) {
NSString *textAlignmentString = [[[self class] styleDictForStyle:style] objectForKey:@"textAlignment"];
if ([textAlignmentString isEqualToString:@"center"]) {
return UIControlContentHorizontalAlignmentCenter;
} else if ([textAlignmentString isEqualToString:@"right"]) {
return UIControlContentHorizontalAlignmentRight;
} else return UIControlContentHorizontalAlignmentLeft;
} else {
return UIControlContentHorizontalAlignmentCenter;
}
}
#pragma mark - Number of Lines
+ (NSInteger)numberOfLinesForStyle:(NSString *)style {
NSInteger numberOfLines = 0; // If left empty, default to 0
if ([[[[self class] styleDictForStyle:style] objectForKey:@"numberOfLines"] integerValue]) {
numberOfLines = [[[[self class] styleDictForStyle:style] objectForKey:@"numberOfLines"] integerValue];
}
return numberOfLines;
}
#pragma mark - Line break mode
+ (UILineBreakMode)lineBreakModeForStyle:(NSString *)style {
// typedef enum {
// UILineBreakModeWordWrap = 0, // Wrap at word boundaries
// UILineBreakModeCharacterWrap, // Wrap at character boundaries
// UILineBreakModeClip, // Simply clip when it hits the end of the rect
// UILineBreakModeHeadTruncation, // Truncate at head of line: "...wxyz". Will truncate multiline text on first line
// UILineBreakModeTailTruncation, // Truncate at tail of line: "abcd...". Will truncate multiline text on last line
// UILineBreakModeMiddleTruncation, // Truncate middle of line: "ab...yz". Will truncate multiline text in the middle
// } UILineBreakMode;
UILineBreakMode lineBreakMode = UILineBreakModeTailTruncation;
if ([[[self class] styleDictForStyle:style] objectForKey:@"lineBreakMode"]) {
NSString *lineBreakModeString = [[[self class] styleDictForStyle:style] objectForKey:@"lineBreakMode"];
if ([lineBreakModeString isEqualToString:@"wordWrap"]) {
lineBreakMode = UILineBreakModeWordWrap;
} else if ([lineBreakModeString isEqualToString:@"characterWrap"]) {
lineBreakMode = UILineBreakModeCharacterWrap;
} else {
lineBreakMode = UILineBreakModeTailTruncation;
}
}
return lineBreakMode;
}
+ (BOOL)adjustsFontSizeToFitWidthForStyle:(NSString *)style {
BOOL adjustsFontSizeToFitWidth = NO;
if ([[[self class] styleDictForStyle:style] objectForKey:@"adjustsFontSizeToFitWidth"]) {
adjustsFontSizeToFitWidth = [[[[self class] styleDictForStyle:style] objectForKey:@"adjustsFontSizeToFitWidth"] boolValue];
}
return adjustsFontSizeToFitWidth;
}
@end