master
1//
2// BlockActionSheet.m
3//
4//
5
6#import "BlockActionSheet.h"
7#import "BlockBackground.h"
8#import "BlockUI.h"
9
10@implementation BlockActionSheet
11
12@synthesize view = _view;
13@synthesize vignetteBackground = _vignetteBackground;
14
15static UIImage *background = nil;
16static UIFont *titleFont = nil;
17static UIFont *buttonFont = nil;
18
19#pragma mark - init
20
21+ (void)initialize
22{
23 if (self == [BlockActionSheet class])
24 {
25 background = [UIImage imageNamed:kActionSheetBackground];
26 background = [[background stretchableImageWithLeftCapWidth:0 topCapHeight:kActionSheetBackgroundCapHeight] retain];
27 titleFont = [kActionSheetTitleFont retain];
28 buttonFont = [kActionSheetButtonFont retain];
29 }
30}
31
32+ (id)sheetWithTitle:(NSString *)title
33{
34 return [[[BlockActionSheet alloc] initWithTitle:title] autorelease];
35}
36
37- (id)initWithTitle:(NSString *)title
38{
39 if ((self = [super init]))
40 {
41 UIWindow *parentView = [BlockBackground sharedInstance];
42 CGRect frame = parentView.bounds;
43
44 _view = [[UIView alloc] initWithFrame:frame];
45
46 _view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
47
48 _blocks = [[NSMutableArray alloc] init];
49 _height = kActionSheetTopMargin;
50
51 if (title)
52 {
53 CGSize size = [title sizeWithFont:titleFont
54 constrainedToSize:CGSizeMake(frame.size.width-kActionSheetBorder*2, 1000)
55 lineBreakMode:NSLineBreakByWordWrapping];
56
57 UILabel *labelView = [[UILabel alloc] initWithFrame:CGRectMake(kActionSheetBorder, _height, frame.size.width-kActionSheetBorder*2, size.height)];
58 labelView.font = titleFont;
59 labelView.numberOfLines = 0;
60 labelView.lineBreakMode = NSLineBreakByWordWrapping;
61 labelView.textColor = kActionSheetTitleTextColor;
62 labelView.backgroundColor = [UIColor clearColor];
63 labelView.textAlignment = NSTextAlignmentCenter;
64 labelView.shadowColor = kActionSheetTitleShadowColor;
65 labelView.shadowOffset = kActionSheetTitleShadowOffset;
66 labelView.text = title;
67
68 labelView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
69
70 [_view addSubview:labelView];
71 [labelView release];
72
73 _height += size.height + 5;
74 }
75 _vignetteBackground = NO;
76 }
77
78 return self;
79}
80
81- (void) dealloc
82{
83 [_view release];
84 [_blocks release];
85 [super dealloc];
86}
87
88- (NSUInteger)buttonCount
89{
90 return _blocks.count;
91}
92
93- (void)addButtonWithTitle:(NSString *)title color:(NSString*)color block:(void (^)())block atIndex:(NSInteger)index
94{
95 if (index >= 0)
96 {
97 [_blocks insertObject:[NSArray arrayWithObjects:
98 block ? [[block copy] autorelease] : [NSNull null],
99 title,
100 color,
101 nil]
102 atIndex:index];
103 }
104 else
105 {
106 [_blocks addObject:[NSArray arrayWithObjects:
107 block ? [[block copy] autorelease] : [NSNull null],
108 title,
109 color,
110 nil]];
111 }
112}
113
114- (void)setDestructiveButtonWithTitle:(NSString *)title block:(void (^)())block
115{
116 [self addButtonWithTitle:title color:@"red" block:block atIndex:-1];
117}
118
119- (void)setCancelButtonWithTitle:(NSString *)title block:(void (^)())block
120{
121 [self addButtonWithTitle:title color:@"black" block:block atIndex:-1];
122}
123
124- (void)addButtonWithTitle:(NSString *)title block:(void (^)())block
125{
126 [self addButtonWithTitle:title color:@"gray" block:block atIndex:-1];
127}
128
129- (void)setDestructiveButtonWithTitle:(NSString *)title atIndex:(NSInteger)index block:(void (^)())block
130{
131 [self addButtonWithTitle:title color:@"red" block:block atIndex:index];
132}
133
134- (void)setCancelButtonWithTitle:(NSString *)title atIndex:(NSInteger)index block:(void (^)())block
135{
136 [self addButtonWithTitle:title color:@"black" block:block atIndex:index];
137}
138
139- (void)addButtonWithTitle:(NSString *)title atIndex:(NSInteger)index block:(void (^)())block
140{
141 [self addButtonWithTitle:title color:@"gray" block:block atIndex:index];
142}
143
144- (void)showInView:(UIView *)view
145{
146 NSUInteger i = 1;
147 for (NSArray *block in _blocks)
148 {
149 NSString *title = [block objectAtIndex:1];
150 NSString *color = [block objectAtIndex:2];
151
152 UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"action-%@-button.png", color]];
153 image = [image stretchableImageWithLeftCapWidth:(int)(image.size.width)>>1 topCapHeight:0];
154
155 UIImage *highlightedImage = [UIImage imageNamed:[NSString stringWithFormat:@"action-%@-button-highlighted.png", color]];
156
157 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
158 button.frame = CGRectMake(kActionSheetBorder, _height, _view.bounds.size.width-kActionSheetBorder*2, kActionSheetButtonHeight);
159 button.titleLabel.font = buttonFont;
160 if (IOS_LESS_THAN_6) {
161#pragma clan diagnostic push
162#pragma clang diagnostic ignored "-Wdeprecated-declarations"
163 button.titleLabel.minimumFontSize = 10;
164#pragma clan diagnostic pop
165 }
166 else {
167 button.titleLabel.minimumScaleFactor = 0.1;
168 }
169 button.titleLabel.adjustsFontSizeToFitWidth = YES;
170 button.titleLabel.textAlignment = NSTextAlignmentCenter;
171 button.titleLabel.shadowOffset = kActionSheetButtonShadowOffset;
172 button.backgroundColor = [UIColor clearColor];
173 button.tag = i++;
174
175 [button setBackgroundImage:image forState:UIControlStateNormal];
176 if (highlightedImage)
177 {
178 [button setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];
179 }
180 [button setTitleColor:kActionSheetButtonTextColor forState:UIControlStateNormal];
181 [button setTitleShadowColor:kActionSheetButtonShadowColor forState:UIControlStateNormal];
182 [button setTitle:title forState:UIControlStateNormal];
183 button.accessibilityLabel = title;
184
185 [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
186
187 button.autoresizingMask = UIViewAutoresizingFlexibleWidth;
188
189 [_view addSubview:button];
190 _height += kActionSheetButtonHeight + kActionSheetBorder;
191 }
192
193 UIImageView *modalBackground = [[UIImageView alloc] initWithFrame:_view.bounds];
194 modalBackground.image = background;
195 modalBackground.contentMode = UIViewContentModeScaleToFill;
196 modalBackground.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
197 [_view insertSubview:modalBackground atIndex:0];
198 [modalBackground release];
199
200 [BlockBackground sharedInstance].vignetteBackground = _vignetteBackground;
201 [[BlockBackground sharedInstance] addToMainWindow:_view];
202 CGRect frame = _view.frame;
203 frame.origin.y = [BlockBackground sharedInstance].bounds.size.height;
204 frame.size.height = _height + kActionSheetBounce;
205 _view.frame = frame;
206
207 __block CGPoint center = _view.center;
208 center.y -= _height + kActionSheetBounce;
209
210 [UIView animateWithDuration:0.4
211 delay:0.0
212 options:UIViewAnimationOptionCurveEaseOut
213 animations:^{
214 [BlockBackground sharedInstance].alpha = 1.0f;
215 _view.center = center;
216 } completion:^(BOOL finished) {
217 [UIView animateWithDuration:0.1
218 delay:0.0
219 options:UIViewAnimationOptionAllowUserInteraction
220 animations:^{
221 center.y += kActionSheetBounce;
222 _view.center = center;
223 } completion:nil];
224 }];
225
226 [self retain];
227}
228
229- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
230{
231 if (buttonIndex >= 0 && buttonIndex < [_blocks count])
232 {
233 id obj = [[_blocks objectAtIndex: buttonIndex] objectAtIndex:0];
234 if (![obj isEqual:[NSNull null]])
235 {
236 ((void (^)())obj)();
237 }
238 }
239
240 if (animated)
241 {
242 CGPoint center = _view.center;
243 center.y += _view.bounds.size.height;
244 [UIView animateWithDuration:0.4
245 delay:0.0
246 options:UIViewAnimationOptionCurveEaseIn
247 animations:^{
248 _view.center = center;
249 [[BlockBackground sharedInstance] reduceAlphaIfEmpty];
250 } completion:^(BOOL finished) {
251 [[BlockBackground sharedInstance] removeView:_view];
252 [_view release]; _view = nil;
253 [self autorelease];
254 }];
255 }
256 else
257 {
258 [[BlockBackground sharedInstance] removeView:_view];
259 [_view release]; _view = nil;
260 [self autorelease];
261 }
262}
263
264#pragma mark - Action
265
266- (void)buttonClicked:(id)sender
267{
268 /* Run the button's block */
269 int buttonIndex = [(UIButton *)sender tag] - 1;
270 [self dismissWithClickedButtonIndex:buttonIndex animated:YES];
271}
272
273@end