// // RQMultiButtons.m // jiaPei // // Created by 张嵘 on 2018/12/26. // Copyright © 2018 JCZ. All rights reserved. // #import "RQMultiButtons.h" @interface RQCustomMultiButtons : NSObject @property NSInteger customId; @property (strong, nonatomic) UIImage *icon; @property (strong, nonatomic) NSString *title; @property (strong, nonatomic) UIColor *backgroundColor; @end @implementation RQCustomMultiButtons @end @interface RQMultiButtons () @property (strong, nonatomic) NSMutableArray *buttons; @property (strong, nonatomic) NSMutableDictionary *buttonIndexTypes; @property (strong, nonatomic) UIView *faderView; @end @implementation RQMultiButtons @synthesize delegate = _delegate, parentView; - (instancetype)initCenteredInWindowWithRadius:(NSInteger)radiusValue { UIWindow *window = [[[UIApplication sharedApplication] delegate] window]; return [self initWithPoint:CGPointMake((CGFloat) (window.frame.size.width * 0.5), (CGFloat) (window.frame.size.height * 0.5)) radius:radiusValue inView:window]; } - (instancetype)initWithPoint:(CGPoint)point radius:(NSInteger)radiusValue inView:(UIView *)inView { self = [super initWithFrame:CGRectMake(point.x - radiusValue, point.y - radiusValue, 2 * radiusValue, 2 * radiusValue)]; if (self) { self.radius = radiusValue; self.bubbleRadius = 40; self.parentView = inView; self.faderAlpha = 0.15; self.faderColor = [UIColor blackColor]; self.customButtons = [[NSMutableArray alloc] init]; self.dismissOnBackgroundTap = YES; UITapGestureRecognizer *tapges = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(shareViewBackgroundTapped:)]; [self addGestureRecognizer:tapges]; } return self; } #pragma mark - #pragma mark Actions - (void)buttonWasTapped:(UIButton *)button { NSInteger buttonType = [_buttonIndexTypes[@(button.tag)] integerValue]; [self shareButtonTappedWithType:buttonType]; } - (void)shareButtonTappedWithType:(NSInteger)buttonType { [self hide]; if([self.delegate respondsToSelector:@selector(rqMultiButtons:tappedButtonWithType:)]) { [self.delegate rqMultiButtons:self tappedButtonWithType:buttonType]; } } #pragma mark - #pragma mark Methods -(void)show { if(!self.isAnimating) { self.isAnimating = YES; [self.parentView addSubview:self]; // Create background _faderView = [[UIView alloc] initWithFrame:self.parentView.bounds]; _faderView.backgroundColor = self.faderColor; _faderView.alpha = 0.0f; if (self.dismissOnBackgroundTap) { UITapGestureRecognizer *tapges = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(shareViewBackgroundTapped:)]; [_faderView addGestureRecognizer:tapges]; } [parentView insertSubview:_faderView belowSubview:self]; [UIView animateWithDuration:0.25 animations:^{ _faderView.alpha = self.faderAlpha; }]; // -- if(_buttons) { _buttons = nil; } _buttons = [[NSMutableArray alloc] init]; _buttonIndexTypes = [[NSMutableDictionary alloc] init]; for (RQCustomMultiButtons *customButton in self.customButtons) { [self createButtonWithIcon:customButton.icon title:customButton.title backgroundColor:customButton.backgroundColor andButtonId:customButton.customId]; } if(_buttons.count == 0) return; float bubbleDistanceFromPivot = self.radius - self.bubbleRadius; float bubblesBetweenAngel = 360 / _buttons.count / 2; float angely = (float) ((180 - bubblesBetweenAngel) * 0.5); float startAngel = 270 - angely; NSMutableArray *coordinates = [NSMutableArray array]; for (NSUInteger i = 0; i < _buttons.count; ++i) { UIButton *button = _buttons[i]; button.tag = i; float angle = startAngel + i * bubblesBetweenAngel; float x = (float) (cos(angle * M_PI / 180) * bubbleDistanceFromPivot + self.radius); float y = (float) (sin(angle * M_PI / 180) * bubbleDistanceFromPivot + self.radius); [coordinates addObject:@{@"x" : @(x), @"y" : @(y)}]; button.transform = CGAffineTransformMakeScale(0.001, 0.001); button.center = CGPointMake(self.radius, self.radius); } NSInteger inetratorI = 0; for (NSDictionary *coordinate in coordinates) { UIButton *button = _buttons[inetratorI]; float delayTime = (float) (inetratorI * 0.1); [self performSelector:@selector(showBubbleWithAnimation:) withObject:@{@"button" : button, @"coordinate" : coordinate} afterDelay:delayTime]; ++inetratorI; } } } -(void)hide { if(!self.isAnimating) { self.isAnimating = YES; NSInteger inetratorI = 0; for (UIButton *button in _buttons) { CGFloat delayTime = (CGFloat) (inetratorI * 0.1); [self performSelector:@selector(hideBubbleWithAnimation:) withObject:button afterDelay:delayTime]; ++inetratorI; } } } #pragma mark - #pragma mark Helper functions -(void)shareViewBackgroundTapped:(UITapGestureRecognizer *)tapGesture { [self hide]; } -(void)showBubbleWithAnimation:(NSDictionary *)info { UIButton *bubble = (UIButton *) info[@"button"]; NSDictionary *coordinate = (NSDictionary *) info[@"coordinate"]; [UIView animateWithDuration:0.25 animations:^{ bubble.center = CGPointMake([coordinate[@"x"] floatValue], [coordinate[@"y"] floatValue]); bubble.alpha = 1; bubble.transform = CGAffineTransformMakeScale(1.2, 1.2); } completion:^(BOOL finished) { [UIView animateWithDuration:0.15 animations:^{ bubble.transform = CGAffineTransformMakeScale(0.8, 0.8); } completion:^(BOOL finished) { [UIView animateWithDuration:0.15 animations:^{ bubble.transform = CGAffineTransformMakeScale(1, 1); } completion:^(BOOL finished) { if(bubble.tag == _buttons.count - 1) self.isAnimating = NO; bubble.layer.shadowColor = [UIColor blackColor].CGColor; bubble.layer.shadowOpacity = 0.2; bubble.layer.shadowOffset = CGSizeMake(0, 1); bubble.layer.shadowRadius = 2; }]; }]; }]; } - (void)hideBubbleWithAnimation:(UIButton *)bubble { [UIView animateWithDuration:0.2 animations:^{ bubble.transform = CGAffineTransformMakeScale(1.2, 1.2); } completion:^(BOOL finished) { [UIView animateWithDuration:0.25 animations:^{ bubble.center = CGPointMake(self.radius, self.radius); bubble.transform = CGAffineTransformMakeScale(0.001, 0.001); bubble.alpha = 0; } completion:^(BOOL finished) { if(bubble.tag == _buttons.count - 1) { self.isAnimating = NO; self.hidden = YES; [UIView animateWithDuration:0.25 animations:^{ _faderView.alpha = 0; } completion:^(BOOL finished) { [_faderView removeFromSuperview]; if([self.delegate respondsToSelector:@selector(rqMultiButtonsDidHide:)]) { [self.delegate rqMultiButtonsDidHide:self]; } [self removeFromSuperview]; }]; } [bubble removeFromSuperview]; }]; }]; } - (void)createButtonWithIcon:(UIImage *)icon title:(NSString *)title backgroundColor:(UIColor *)color andButtonId:(NSInteger)buttonId { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button addTarget:self action:@selector(buttonWasTapped:) forControlEvents:UIControlEventTouchUpInside]; button.frame = CGRectMake(0, 0, 2 * self.bubbleRadius, 2 * self.bubbleRadius); // Circle background UIView *circle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 2 * self.bubbleRadius, 2 * self.bubbleRadius)]; circle.backgroundColor = color; circle.layer.cornerRadius = self.bubbleRadius; circle.layer.masksToBounds = YES; circle.opaque = NO; circle.alpha = 0.97; // Circle icon UIImageView *iconView = [[UIImageView alloc] initWithImage:icon]; CGRect f = iconView.frame; f.origin.x = (CGFloat) ((circle.frame.size.width - f.size.width) * 0.5); f.origin.y = [title isEqualToString:@"随机练习"]? (CGFloat) ((circle.frame.size.height - f.size.height) * 0.5 - 5) : ((CGFloat) ((circle.frame.size.height - f.size.height) * 0.5 + 10)); iconView.frame = f; [circle addSubview:iconView]; UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 2 * self.bubbleRadius - 20, 2 * self.bubbleRadius, 10)]; titleLabel.text = title; titleLabel.font = [UIFont systemFontOfSize:10]; titleLabel.textColor = defGreen; titleLabel.textAlignment = NSTextAlignmentCenter; [circle addSubview:titleLabel]; [button setBackgroundImage:[self imageWithView:circle] forState:UIControlStateNormal]; [_buttons addObject:button]; _buttonIndexTypes[@(_buttons.count - 1)] = @(buttonId); [self addSubview:button]; } - (void)createButtonWithIcon:(NSString *)iconName backgroundColor:(NSInteger)rgb andType:(RQMultiButtonsType)type { NSBundle *classBundle = [NSBundle bundleForClass:[self class]]; NSBundle *resourcesBundle = [NSBundle bundleWithPath:[NSString stringWithFormat:@"%@/AAShareBubbles.bundle", classBundle.bundlePath]]; UIImage *icon = [UIImage imageNamed:iconName inBundle:resourcesBundle compatibleWithTraitCollection:nil]; UIColor *color = [self colorFromRGB:rgb]; [self createButtonWithIcon:icon title:@"顺序练习" backgroundColor:color andButtonId:type]; } - (void)addCustomButtonWithIcon:(UIImage *)icon title:(NSString *)title backgroundColor:(UIColor *)color andButtonId:(NSInteger)buttonId { NSAssert(buttonId >= 100, @"Custom Button Ids must be >= 100"); RQCustomMultiButtons *customButton = [[RQCustomMultiButtons alloc] init]; customButton.backgroundColor = color; customButton.icon = icon; customButton.title = title; customButton.customId = buttonId; [self.customButtons addObject:customButton]; } - (UIColor *)colorFromRGB:(NSInteger)rgb { return [UIColor colorWithRed:((float)((rgb & 0xFF0000) >> 16))/255.0 green:((float)((rgb & 0xFF00) >> 8))/255.0 blue:((float)(rgb & 0xFF))/255.0 alpha:1.0]; } - (UIImage *)imageWithView:(UIView *)view { UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; } @end