From 179cc1cfe6ecb2ecc0baa71ffe921c3d11c939f4 Mon Sep 17 00:00:00 2001 From: Christian Klaproth Date: Fri, 1 Sep 2017 18:22:21 +0200 Subject: [PATCH] Title support for buttons #11 --- CKCircleMenuView/CKCircleMenuView.h | 14 ++++++ CKCircleMenuView/CKCircleMenuView.m | 44 +++++++++++++++++-- .../CircleMenuDemo/ViewController.m | 3 +- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/CKCircleMenuView/CKCircleMenuView.h b/CKCircleMenuView/CKCircleMenuView.h index 36f00b8..8e1b5f2 100644 --- a/CKCircleMenuView/CKCircleMenuView.h +++ b/CKCircleMenuView/CKCircleMenuView.h @@ -45,6 +45,8 @@ extern NSString* const CIRCLE_MENU_BACKGROUND_BLUR; extern NSString* const CIRCLE_MENU_BUTTON_TINT; extern NSString* const CIRCLE_MENU_ALLOW_ANIMATION_INTERACTION; extern NSString* const CIRCLE_MENU_STARTING_ANGLE; +extern NSString* const CIRCLE_MENU_BUTTON_TITLE_VISIBLE; +extern NSString* const CIRCLE_MENU_BUTTON_TITLE_FONT_SIZE; typedef enum { CircleMenuDirectionUp = 1, @@ -77,6 +79,18 @@ typedef enum { */ - (id)initAtOrigin:(CGPoint)aPoint usingOptions:(NSDictionary*)anOptionsDictionary withImageArray:(NSArray*)anImageArray; +/** + * Initializes the CKCircleMenuView. + * @param aPoint the center of the menu's circle + * @param anOptionsDictionary optional configuration, may be nil + * @param anImageArray array of images to be used for the buttons, + * currently icon images should be 32x32 points + * (64x64 px for retina) + * @param aTitleArray array of strings with titles that are displayed + * below the button icons + */ +- (id)initAtOrigin:(CGPoint)aPoint usingOptions:(NSDictionary*)anOptionsDictionary withImageArray:(NSArray*)anImageArray andTitles:(NSArray*)aTitleArray; + /** * Opens the menu with the buttons and settings specified in the * initializer. diff --git a/CKCircleMenuView/CKCircleMenuView.m b/CKCircleMenuView/CKCircleMenuView.m index 8bc821d..0096174 100644 --- a/CKCircleMenuView/CKCircleMenuView.m +++ b/CKCircleMenuView/CKCircleMenuView.m @@ -28,6 +28,8 @@ @interface CKCircleMenuView() @property (nonatomic) BOOL visualFxMode; @property (nonatomic) BOOL buttonTintMode; @property (nonatomic) BOOL allowAnimationInteraction; +@property (nonatomic) BOOL buttonTitleVisible; +@property (nonatomic) CGFloat buttonTitleFontSize; @property (nonatomic, weak) UIView* clippingView; @@ -56,6 +58,8 @@ @interface CKCircleMenuView() NSString* const CIRCLE_MENU_BUTTON_TINT = @"kCircleMenuButtonTint"; NSString* const CIRCLE_MENU_ALLOW_ANIMATION_INTERACTION = @"kCircleMenuAllowAnimationInteraction"; NSString* const CIRCLE_MENU_STARTING_ANGLE = @"kCircleMenuStartingAngle"; +NSString* const CIRCLE_MENU_BUTTON_TITLE_VISIBLE = @"kCircleMenuButtonTitleVisible"; +NSString* const CIRCLE_MENU_BUTTON_TITLE_FONT_SIZE = @"kCircleMenuButtonTitleFontSize"; @implementation CKCircleMenuView @@ -100,6 +104,11 @@ - (id)initWithOptions:(NSDictionary*)anOptionsDictionary self.visualFxMode = [[anOptionsDictionary valueForKey:CIRCLE_MENU_BACKGROUND_BLUR] boolValue]; self.buttonTintMode = [[anOptionsDictionary valueForKey:CIRCLE_MENU_BUTTON_TINT] boolValue]; self.allowAnimationInteraction = [[anOptionsDictionary valueForKey:CIRCLE_MENU_ALLOW_ANIMATION_INTERACTION] boolValue]; + self.buttonTitleVisible = [[anOptionsDictionary valueForKey:CIRCLE_MENU_BUTTON_TITLE_VISIBLE] boolValue]; + self.buttonTitleFontSize = [[anOptionsDictionary valueForKey:CIRCLE_MENU_BUTTON_TITLE_FONT_SIZE] doubleValue]; + if (!self.buttonTitleFontSize) { + self.buttonTitleFontSize = 11.0; + } } else { // using some default settings self.innerViewColor = [UIColor colorWithRed:0.0 green:0.25 blue:0.5 alpha:1.0]; @@ -117,22 +126,35 @@ - (id)initWithOptions:(NSDictionary*)anOptionsDictionary self.visualFxMode = NO; self.buttonTintMode = NO; self.allowAnimationInteraction = NO; + self.buttonTitleVisible = NO; + self.buttonTitleFontSize = 11.0; } } return self; } - (id)initAtOrigin:(CGPoint)aPoint usingOptions:(NSDictionary *)anOptionsDictionary withImageArray:(NSArray *)anImageArray +{ + self = [self initAtOrigin:aPoint usingOptions:anOptionsDictionary withImageArray:anImageArray andTitles:@[]]; + return self; +} + +- (id)initAtOrigin:(CGPoint)aPoint usingOptions:(NSDictionary*)anOptionsDictionary withImageArray:(NSArray*)anImageArray andTitles:(NSArray*)aTitleArray; { self = [self initWithOptions:anOptionsDictionary]; if (self) { int tTag = 1; for (UIImage* img in anImageArray) { - UIView* tView = [self createButtonViewWithImage:img andTag:tTag]; + UIView* tView; + if ([aTitleArray count] >= tTag) { + tView = [self createButtonViewWithImage:img andTag:tTag andTitle:aTitleArray[tTag-1]]; + } else { + tView = [self createButtonViewWithImage:img andTag:tTag andTitle:nil]; + } [self.buttons addObject:tView]; tTag += 1; } - + self.frame = [self calculateFrameWithOrigin:aPoint]; } return self; @@ -146,7 +168,7 @@ - (id)initAtOrigin:(CGPoint)aPoint usingOptions:(NSDictionary *)anOptionsDiction va_list args; va_start(args, anImage); for (UIImage* img = anImage; img != nil; img = va_arg(args, UIImage*)) { - UIView* tView = [self createButtonViewWithImage:img andTag:tTag]; + UIView* tView = [self createButtonViewWithImage:img andTag:tTag andTitle:nil]; [self.buttons addObject:tView]; tTag += 1; } @@ -188,7 +210,7 @@ - (CGRect)calculateFrameWithOrigin:(CGPoint)aPoint { * @param aTag unique identifier (should be index + 1) * @return UIView to be used as button */ -- (UIView*)createButtonViewWithImage:(UIImage*)anImage andTag:(int)aTag +- (UIView*)createButtonViewWithImage:(UIImage*)anImage andTag:(int)aTag andTitle:(NSString*)aTitle { UIButton* tButton; if (self.buttonTintMode) { @@ -220,6 +242,20 @@ - (UIView*)createButtonViewWithImage:(UIImage*)anImage andTag:(int)aTag [self applyInactiveDepthToButtonView:tInnerView]; } + // Support for displaying button titles + if (self.buttonTitleVisible && aTitle) { + UILabel* tLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, self.buttonRadius * 2 - self.buttonTitleFontSize * 2.15, self.buttonRadius * 2, self.buttonTitleFontSize + 2.0)]; + tLabel.textAlignment = NSTextAlignmentCenter; + tLabel.font = [UIFont systemFontOfSize:self.buttonTitleFontSize]; + tLabel.textColor = self.borderViewColor; + tLabel.text = aTitle; + tLabel.userInteractionEnabled = NO; + [tInnerView addSubview:tLabel]; + + // Make some space for label below button + tButton.layer.affineTransform = CGAffineTransformMakeTranslation(0.0, -self.buttonTitleFontSize / 1.9); + } + tInnerView.tag = aTag + TAG_INNER_VIEW_OFFSET; [tInnerView addSubview:tButton]; diff --git a/CircleMenuDemo/CircleMenuDemo/ViewController.m b/CircleMenuDemo/CircleMenuDemo/ViewController.m index 9f11d8b..1feedfe 100644 --- a/CircleMenuDemo/CircleMenuDemo/ViewController.m +++ b/CircleMenuDemo/CircleMenuDemo/ViewController.m @@ -121,8 +121,9 @@ - (IBAction)longPressGestureRecognized:(UILongPressGestureRecognizer *)sender [tOptions setValue:[NSNumber numberWithBool:NO] forKey:CIRCLE_MENU_LINE_MODE]; [tOptions setValue:[NSNumber numberWithBool:NO] forKey:CIRCLE_MENU_BACKGROUND_BLUR]; [tOptions setValue:[NSNumber numberWithBool:NO] forKey:CIRCLE_MENU_BUTTON_TINT]; + [tOptions setValue:[NSNumber numberWithBool:YES] forKey:CIRCLE_MENU_BUTTON_TITLE_VISIBLE]; - CKCircleMenuView* tMenu = [[CKCircleMenuView alloc] initAtOrigin:tPoint usingOptions:tOptions withImageArray:self.imageArray]; + CKCircleMenuView* tMenu = [[CKCircleMenuView alloc] initAtOrigin:tPoint usingOptions:tOptions withImageArray:self.imageArray andTitles:@[@"Trash"]]; tMenu.delegate = self; [self.demoAreaLabel addSubview:tMenu]; [tMenu openMenuWithRecognizer:sender];