// // BlockActionSheet.m // // #import "BlockActionSheet.h" #import "BlockBackground.h" #import "BlockUI.h" @implementation BlockActionSheet @synthesize view = _view; @synthesize vignetteBackground = _vignetteBackground; static UIImage *background = nil; static UIFont *titleFont = nil; static UIFont *buttonFont = nil; #pragma mark - init + (void)initialize { if (self == [BlockActionSheet class]) { background = [UIImage imageNamed:kActionSheetBackground]; background = [[background stretchableImageWithLeftCapWidth:0 topCapHeight:kActionSheetBackgroundCapHeight] retain]; titleFont = [kActionSheetTitleFont retain]; buttonFont = [kActionSheetButtonFont retain]; } } + (id)sheetWithTitle:(NSString *)title { return [[[BlockActionSheet alloc] initWithTitle:title] autorelease]; } - (id)initWithTitle:(NSString *)title { if ((self = [super init])) { UIWindow *parentView = [BlockBackground sharedInstance]; CGRect frame = parentView.bounds; _view = [[UIView alloc] initWithFrame:frame]; _view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; _blocks = [[NSMutableArray alloc] init]; _height = kActionSheetTopMargin; if (title) { CGSize size = [title sizeWithFont:titleFont constrainedToSize:CGSizeMake(frame.size.width-kActionSheetBorder*2, 1000) lineBreakMode:NSLineBreakByWordWrapping]; UILabel *labelView = [[UILabel alloc] initWithFrame:CGRectMake(kActionSheetBorder, _height, frame.size.width-kActionSheetBorder*2, size.height)]; labelView.font = titleFont; labelView.numberOfLines = 0; labelView.lineBreakMode = NSLineBreakByWordWrapping; labelView.textColor = kActionSheetTitleTextColor; labelView.backgroundColor = [UIColor clearColor]; labelView.textAlignment = NSTextAlignmentCenter; labelView.shadowColor = kActionSheetTitleShadowColor; labelView.shadowOffset = kActionSheetTitleShadowOffset; labelView.text = title; labelView.autoresizingMask = UIViewAutoresizingFlexibleWidth; [_view addSubview:labelView]; [labelView release]; _height += size.height + 5; } _vignetteBackground = NO; } return self; } - (void) dealloc { [_view release]; [_blocks release]; [super dealloc]; } - (NSUInteger)buttonCount { return _blocks.count; } - (void)addButtonWithTitle:(NSString *)title color:(NSString*)color block:(void (^)())block atIndex:(NSInteger)index { if (index >= 0) { [_blocks insertObject:[NSArray arrayWithObjects: block ? [[block copy] autorelease] : [NSNull null], title, color, nil] atIndex:index]; } else { [_blocks addObject:[NSArray arrayWithObjects: block ? [[block copy] autorelease] : [NSNull null], title, color, nil]]; } } - (void)setDestructiveButtonWithTitle:(NSString *)title block:(void (^)())block { [self addButtonWithTitle:title color:@"red" block:block atIndex:-1]; } - (void)setCancelButtonWithTitle:(NSString *)title block:(void (^)())block { [self addButtonWithTitle:title color:@"black" block:block atIndex:-1]; } - (void)addButtonWithTitle:(NSString *)title block:(void (^)())block { [self addButtonWithTitle:title color:@"gray" block:block atIndex:-1]; } - (void)setDestructiveButtonWithTitle:(NSString *)title atIndex:(NSInteger)index block:(void (^)())block { [self addButtonWithTitle:title color:@"red" block:block atIndex:index]; } - (void)setCancelButtonWithTitle:(NSString *)title atIndex:(NSInteger)index block:(void (^)())block { [self addButtonWithTitle:title color:@"black" block:block atIndex:index]; } - (void)addButtonWithTitle:(NSString *)title atIndex:(NSInteger)index block:(void (^)())block { [self addButtonWithTitle:title color:@"gray" block:block atIndex:index]; } - (void)showInView:(UIView *)view { NSUInteger i = 1; for (NSArray *block in _blocks) { NSString *title = [block objectAtIndex:1]; NSString *color = [block objectAtIndex:2]; UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"action-%@-button.png", color]]; image = [image stretchableImageWithLeftCapWidth:(int)(image.size.width)>>1 topCapHeight:0]; UIImage *highlightedImage = [UIImage imageNamed:[NSString stringWithFormat:@"action-%@-button-highlighted.png", color]]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(kActionSheetBorder, _height, _view.bounds.size.width-kActionSheetBorder*2, kActionSheetButtonHeight); button.titleLabel.font = buttonFont; if (IOS_LESS_THAN_6) { #pragma clan diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" button.titleLabel.minimumFontSize = 10; #pragma clan diagnostic pop } else { button.titleLabel.minimumScaleFactor = 0.1; } button.titleLabel.adjustsFontSizeToFitWidth = YES; button.titleLabel.textAlignment = NSTextAlignmentCenter; button.titleLabel.shadowOffset = kActionSheetButtonShadowOffset; button.backgroundColor = [UIColor clearColor]; button.tag = i++; [button setBackgroundImage:image forState:UIControlStateNormal]; if (highlightedImage) { [button setBackgroundImage:highlightedImage forState:UIControlStateHighlighted]; } [button setTitleColor:kActionSheetButtonTextColor forState:UIControlStateNormal]; [button setTitleShadowColor:kActionSheetButtonShadowColor forState:UIControlStateNormal]; [button setTitle:title forState:UIControlStateNormal]; button.accessibilityLabel = title; [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; button.autoresizingMask = UIViewAutoresizingFlexibleWidth; [_view addSubview:button]; _height += kActionSheetButtonHeight + kActionSheetBorder; } UIImageView *modalBackground = [[UIImageView alloc] initWithFrame:_view.bounds]; modalBackground.image = background; modalBackground.contentMode = UIViewContentModeScaleToFill; modalBackground.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [_view insertSubview:modalBackground atIndex:0]; [modalBackground release]; [BlockBackground sharedInstance].vignetteBackground = _vignetteBackground; [[BlockBackground sharedInstance] addToMainWindow:_view]; CGRect frame = _view.frame; frame.origin.y = [BlockBackground sharedInstance].bounds.size.height; frame.size.height = _height + kActionSheetBounce; _view.frame = frame; __block CGPoint center = _view.center; center.y -= _height + kActionSheetBounce; [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ [BlockBackground sharedInstance].alpha = 1.0f; _view.center = center; } completion:^(BOOL finished) { [UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ center.y += kActionSheetBounce; _view.center = center; } completion:nil]; }]; [self retain]; } - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { if (buttonIndex >= 0 && buttonIndex < [_blocks count]) { id obj = [[_blocks objectAtIndex: buttonIndex] objectAtIndex:0]; if (![obj isEqual:[NSNull null]]) { ((void (^)())obj)(); } } if (animated) { CGPoint center = _view.center; center.y += _view.bounds.size.height; [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ _view.center = center; [[BlockBackground sharedInstance] reduceAlphaIfEmpty]; } completion:^(BOOL finished) { [[BlockBackground sharedInstance] removeView:_view]; [_view release]; _view = nil; [self autorelease]; }]; } else { [[BlockBackground sharedInstance] removeView:_view]; [_view release]; _view = nil; [self autorelease]; } } #pragma mark - Action - (void)buttonClicked:(id)sender { /* Run the button's block */ int buttonIndex = [(UIButton *)sender tag] - 1; [self dismissWithClickedButtonIndex:buttonIndex animated:YES]; } @end