Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 299 lines (240 sloc) 9.334 kb
4e1ebad5 »
2011-07-16 Second commit...
1 //
2 // MAConfirmButton.m
3 //
4 // Created by Mike on 11-03-28.
5 // Copyright 2011 Mike Ahmarani. All rights reserved.
6 //
7
8 #import "MAConfirmButton.h"
9 #import "UIColor-Expanded.h"
10
11 #define kHeight 26.0
12 #define kPadding 20.0
13 #define kFontSize 14.0
14
15 @interface MAConfirmButton ()
16
17 @property (nonatomic, copy) NSString *title;
18 @property (nonatomic, copy) NSString *confirm;
19 @property (nonatomic, copy) NSString *disabled;
20 @property (nonatomic, retain) UIColor *tint;
21
22 - (void)toggle;
23 - (void)setupLayers;
24 - (void)cancel;
25 - (void)lighten;
26 - (void)darken;
27
28 @end
29
30 @implementation MAConfirmButton
31
32 @synthesize title, confirm, disabled, tint;
33
34 - (void)dealloc{
35 [title release];
36 [confirm release];
37 [disabled release];
38 [tint release];
39 [super dealloc];
40 }
41
42 + (MAConfirmButton *)buttonWithTitle:(NSString *)titleString confirm:(NSString *)confirmString{
43 MAConfirmButton *button = [[[super alloc] initWithTitle:titleString confirm:confirmString] autorelease];
44 return button;
45 }
46
47 + (MAConfirmButton *)buttonWithDisabledTitle:(NSString *)disabledString{
48 MAConfirmButton *button = [[[super alloc] initWithDisabledTitle:disabledString] autorelease];
49 return button;
50 }
51
52 - (id)initWithDisabledTitle:(NSString *)disabledString{
53 self = [super initWithFrame:CGRectZero];
54 if(self != nil){
55 disabled = [disabledString retain];
56
57 self.layer.needsDisplayOnBoundsChange = YES;
58
59 CGSize size = [disabled sizeWithFont:[UIFont boldSystemFontOfSize:kFontSize]];
60 CGRect r = self.frame;
61 r.size.height = kHeight;
62 r.size.width = size.width+kPadding;
63 self.frame = r;
64
65 [self setTitle:disabled forState:UIControlStateNormal];
66 [self setTitleColor:[UIColor colorWithWhite:0.6 alpha:1] forState:UIControlStateNormal];
67 [self setTitleShadowColor:[UIColor colorWithWhite:1 alpha:1] forState:UIControlStateNormal];
68
69 self.titleLabel.textAlignment = UITextAlignmentCenter;
70 self.titleLabel.shadowOffset = CGSizeMake(0, 1);
71 self.titleLabel.backgroundColor = [UIColor clearColor];
72 self.titleLabel.font = [UIFont boldSystemFontOfSize:kFontSize];
73 self.tint = [UIColor colorWithWhite:0.85 alpha:1];
74
75 [self setupLayers];
76 }
77 return self;
78 }
79
80 - (id)initWithTitle:(NSString *)titleString confirm:(NSString *)confirmString{
81 self = [super initWithFrame:CGRectZero];
82 if(self != nil){
83
84 self.title = [titleString retain];
85 self.confirm = [confirmString retain];
86
87 self.layer.needsDisplayOnBoundsChange = YES;
88
89 CGSize size = [title sizeWithFont:[UIFont boldSystemFontOfSize:kFontSize]];
90 CGRect r = self.frame;
91 r.size.height = kHeight;
92 r.size.width = size.width+kPadding;
93 self.frame = r;
94
95 [self setTitle:title forState:UIControlStateNormal];
96 [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
97 [self setTitleShadowColor:[UIColor colorWithWhite:0 alpha:0.5] forState:UIControlStateNormal];
98
99 self.titleLabel.textAlignment = UITextAlignmentCenter;
100 self.titleLabel.shadowOffset = CGSizeMake(0, -1);
101 self.titleLabel.backgroundColor = [UIColor clearColor];
102 self.titleLabel.font = [UIFont boldSystemFontOfSize:kFontSize];
103 self.tint = [UIColor colorWithRed:0.220 green:0.357 blue:0.608 alpha:1];
104
105 [self setupLayers];
106 }
107 return self;
108 }
109
110 - (void)toggle{
111
112 self.titleLabel.alpha = 0;
113
114 CGSize size;
115
116 if(disabled){
117 [self setTitle:disabled forState:UIControlStateNormal];
118 [self setTitleColor:[UIColor colorWithWhite:0.6 alpha:1] forState:UIControlStateNormal];
119 [self setTitleShadowColor:[UIColor colorWithWhite:1 alpha:1] forState:UIControlStateNormal];
120 self.titleLabel.shadowOffset = CGSizeMake(0, 1);
121 size = [disabled sizeWithFont:[UIFont boldSystemFontOfSize:kFontSize]];
122 }else if(selected){
123 [self setTitle:confirm forState:UIControlStateNormal];
124 size = [confirm sizeWithFont:[UIFont boldSystemFontOfSize:kFontSize]];
125 }else{
126 [self setTitle:title forState:UIControlStateNormal];
127 size = [title sizeWithFont:[UIFont boldSystemFontOfSize:kFontSize]];
128 }
129
130 size.width += kPadding;
131 float offset = size.width - self.frame.size.width;
132
133 [CATransaction begin];
134 [CATransaction setAnimationDuration:0.25];
135 [CATransaction setCompletionBlock:^{
136 //Readjust button frame for new touch area, move layers back now that animation is done
137
138 CGRect frameRect = self.frame;
139 frameRect.origin.x = frameRect.origin.x - offset;
140 frameRect.size.width = frameRect.size.width + offset;
141 self.frame = frameRect;
142
143 [CATransaction setDisableActions:YES];
144 for(CALayer *layer in self.layer.sublayers){
145 CGRect rect = layer.frame;
146 rect.origin.x = rect.origin.x+offset;
147 layer.frame = rect;
148 }
149 [CATransaction commit];
150
151 self.titleLabel.alpha = 1;
152 [self setNeedsLayout];
153 }];
154
155 UIColor *greenColor = [UIColor colorWithRed:0.439 green:0.741 blue:0.314 alpha:1.];
156
157 //Animate color change
158 CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
159 colorAnimation.removedOnCompletion = NO;
160 colorAnimation.fillMode = kCAFillModeForwards;
161
162 if(disabled){
163 colorAnimation.fromValue = (id)greenColor.CGColor;
164 colorAnimation.toValue = (id)[UIColor colorWithWhite:0.85 alpha:1].CGColor;
165 }else{
166 colorAnimation.fromValue = selected ? (id)tint.CGColor : (id)greenColor.CGColor;
167 colorAnimation.toValue = selected ? (id)greenColor.CGColor : (id)tint.CGColor;
168 }
169
170 [colorLayer addAnimation:colorAnimation forKey:@"colorAnimation"];
171
172 //Animate layer scaling
173 for(CALayer *layer in self.layer.sublayers){
174 CGRect rect = layer.frame;
175 rect.origin.x = rect.origin.x-offset;
176 rect.size.width = rect.size.width+offset;
177 layer.frame = rect;
178 }
179
180 [CATransaction commit];
181
182 [self setNeedsDisplay];
183 }
184
185 - (void)setupLayers{
186
187 CAGradientLayer *bevelLayer = [CAGradientLayer layer];
188 bevelLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
189 bevelLayer.colors = [NSArray arrayWithObjects:(id)[UIColor colorWithWhite:0 alpha:0.5].CGColor, [UIColor whiteColor].CGColor, nil];
190 bevelLayer.cornerRadius = 4.0;
191 bevelLayer.needsDisplayOnBoundsChange = YES;
192
193 colorLayer = [CALayer layer];
194 colorLayer.frame = CGRectMake(0, 1, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)-2);
195 colorLayer.borderColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
196 colorLayer.backgroundColor = tint.CGColor;
197 colorLayer.borderWidth = 1.0;
198 colorLayer.cornerRadius = 4.0;
199 colorLayer.needsDisplayOnBoundsChange = YES;
200
201 CAGradientLayer *colorGradient = [CAGradientLayer layer];
202 colorGradient.frame = CGRectMake(0, 1, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)-2);
203 colorGradient.colors = [NSArray arrayWithObjects:(id)[UIColor colorWithWhite:1 alpha:0.1].CGColor, [UIColor colorWithWhite:0.2 alpha:0.1].CGColor , nil];
204 colorGradient.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:1.0], nil];
205 colorGradient.cornerRadius = 4.0;
206 colorGradient.needsDisplayOnBoundsChange = YES;
207
208 [self.layer addSublayer:bevelLayer];
209 [self.layer addSublayer:colorLayer];
210 [self.layer addSublayer:colorGradient];
211 [self bringSubviewToFront:self.titleLabel];
212
213 }
214
215 - (void)setSelected:(BOOL)s{
216 selected = s;
217 [self toggle];
218 }
219
220 - (void)disableWithTitle:(NSString *)disabledString{
221 self.disabled = [disabledString retain];
222 [self toggle];
223 }
224
225 - (void)setAnchor:(CGPoint)anchor{
226 //Top-right point of the view (MUST BE SET LAST)
227 CGRect rect = self.frame;
228 rect.origin = CGPointMake(anchor.x - rect.size.width, anchor.y);
229 self.frame = rect;
230 }
231
232 - (void)setTintColor:(UIColor *)color{
233 self.tint = [UIColor colorWithHue:color.hue saturation:color.saturation+0.15 brightness:color.brightness alpha:1];
234 colorLayer.backgroundColor = tint.CGColor;
235 [self setNeedsDisplay];
236 }
237
238 - (void)darken{
239 darkenLayer = [CALayer layer];
240 darkenLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
241 darkenLayer.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2].CGColor;
242 darkenLayer.cornerRadius = 4.0;
243 darkenLayer.needsDisplayOnBoundsChange = YES;
244 [self.layer addSublayer:darkenLayer];
245 }
246
247 - (void)lighten{
248 if(darkenLayer){
249 [darkenLayer removeFromSuperlayer];
250 darkenLayer = nil;
251 }
252 }
253
254 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
255 if(!disabled && !confirmed){
256 [self darken];
257 }
258 [super touchesBegan:touches withEvent:event];
259 }
260
261 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
262
263 if(!disabled && !confirmed){
264 if(!CGRectContainsPoint(self.frame, [[touches anyObject] locationInView:self.superview])){ //TouchUpOutside (Cancelled Touch)
265 [self lighten];
266 [super touchesCancelled:touches withEvent:event];
267 }else if(selected){
268 [self lighten];
269 confirmed = YES;
270 [cancelOverlay removeFromSuperview];
271 cancelOverlay = nil;
272 [super touchesEnded:touches withEvent:event];
273 }else{
274 [self lighten];
275 self.selected = YES;
276 cancelOverlay = [UIButton buttonWithType:UIButtonTypeCustom];
277 [cancelOverlay setFrame:CGRectMake(0, 0, 1024, 1024)];
278 [cancelOverlay addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchDown];
279 [self.superview addSubview:cancelOverlay];
280 [self.superview bringSubviewToFront:self];
281 }
282 }
283 }
284
285 - (void)cancel{
286 if(cancelOverlay){
287 [cancelOverlay removeFromSuperview];
288 cancelOverlay = nil;
289 }
290 self.selected = NO;
291 }
292
293 - (void)resetDisabled {
294 self.disabled = nil;
295 [self toggle];
296 }
297
298 @end
Something went wrong with that request. Please try again.