From 6463a4b778b3a7988b2690e3f99ace407ce07905 Mon Sep 17 00:00:00 2001 From: Javier Soto Date: Mon, 30 Sep 2013 19:01:42 -0700 Subject: [PATCH 1/8] Better Apple-Doc compatible syntax. --- JSBadgeView/JSBadgeView.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/JSBadgeView/JSBadgeView.h b/JSBadgeView/JSBadgeView.h index 1ac6595..03c4f0c 100644 --- a/JSBadgeView/JSBadgeView.h +++ b/JSBadgeView/JSBadgeView.h @@ -52,33 +52,33 @@ typedef NS_ENUM(NSUInteger, JSBadgeViewAlignment) @property (nonatomic, strong) UIColor *badgeBackgroundColor UI_APPEARANCE_SELECTOR; /** - * @discussion color of the overlay circle at the top. Default is semi-transparent white. + * Color of the overlay circle at the top. Default is semi-transparent white. */ @property (nonatomic, strong) UIColor *badgeOverlayColor UI_APPEARANCE_SELECTOR; /** - * @discussion color of the badge shadow. Default is semi-transparent black. + * Color of the badge shadow. Default is semi-transparent black. */ @property (nonatomic, strong) UIColor *badgeShadowColor UI_APPEARANCE_SELECTOR; /** - * @discussion color of the circle around the badge. Default is white. + * Color of the circle around the badge. Default is white. */ @property (nonatomic, strong) UIColor *badgeStrokeColor UI_APPEARANCE_SELECTOR; /** - * @discussion allows to shift the badge by x and y points. + * Allows to shift the badge by x and y points. */ @property (nonatomic, assign) CGPoint badgePositionAdjustment UI_APPEARANCE_SELECTOR; /** - * @discussion (optional) If not provided, the superview frame is used. * You can use this to position the view if you're drawing it using drawRect instead of `-addSubview:` + * (optional) If not provided, the superview frame is used. */ @property (nonatomic, assign) CGRect frameToPositionInRelationWith UI_APPEARANCE_SELECTOR; /** - * @discussion optionally init using this method to have the badge automatically added to another view. + * Optionally init using this method to have the badge automatically added to another view. */ - (id)initWithParentView:(UIView *)parentView alignment:(JSBadgeViewAlignment)alignment; From 835d62008642bc3d06fe640b9435a54b4cccf2a7 Mon Sep 17 00:00:00 2001 From: Javier Soto Date: Mon, 30 Sep 2013 19:39:44 -0700 Subject: [PATCH 2/8] Added two new properties and adding style for iOS 7 that is automatically used unless we're in "legacy" mode. Now setting the default style using UIAppearance on +initialize because it will be called before *your* initialize code or wherever you put your UIAppearance calls. Fixes #8 --- JSBadgeView/JSBadgeView.h | 10 +++ JSBadgeView/JSBadgeView.m | 155 ++++++++++++++++++++++++++------------ 2 files changed, 115 insertions(+), 50 deletions(-) diff --git a/JSBadgeView/JSBadgeView.h b/JSBadgeView/JSBadgeView.h index 03c4f0c..49edfc9 100644 --- a/JSBadgeView/JSBadgeView.h +++ b/JSBadgeView/JSBadgeView.h @@ -61,6 +61,16 @@ typedef NS_ENUM(NSUInteger, JSBadgeViewAlignment) */ @property (nonatomic, strong) UIColor *badgeShadowColor UI_APPEARANCE_SELECTOR; +/** + * Offset of the badge shadow. Default is 3.0 points down. + */ +@property (nonatomic, assign) CGSize badgeShadowSize UI_APPEARANCE_SELECTOR; + +/** + * Width of the circle around the badge. Default is 2.0 points. + */ +@property (nonatomic, assign) CGFloat badgeStrokeWidth UI_APPEARANCE_SELECTOR; + /** * Color of the circle around the badge. Default is white. */ diff --git a/JSBadgeView/JSBadgeView.m b/JSBadgeView/JSBadgeView.m index 7b3807d..96cbee9 100644 --- a/JSBadgeView/JSBadgeView.m +++ b/JSBadgeView/JSBadgeView.m @@ -28,48 +28,90 @@ of this software and associated documentation files (the "Software"), to deal #error JSBadgeView must be compiled with ARC. #endif -#define kDefaultBadgeTextColor [UIColor whiteColor] -#define kDefaultBadgeBackgroundColor [UIColor redColor] -#define kDefaultOverlayColor [UIColor colorWithWhite:1.0f alpha:0.3] +static const CGFloat JSBadgeViewShadowRadius = 1.0f; +static const CGFloat JSBadgeViewHeight = 16.0f; +static const CGFloat JSBadgeViewTextSideMargin = 8.0f; +static const CGFloat JSBadgeViewCornerRadius = 10.0f; -#define kDefaultBadgeTextFont [UIFont boldSystemFontOfSize:[UIFont systemFontSize]] - -#define kDefaultBadgeShadowColor [UIColor clearColor] - -#define kDefaultBadgeStrokeColor [UIColor whiteColor] -#define kBadgeStrokeWidth 2.0f +// Thanks to Peter Steinberger: https://gist.github.com/steipete/6526860 +static BOOL JSBadgeViewIsUIKitFlatMode(void) +{ + static BOOL isUIKitFlatMode = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +#ifndef kCFCoreFoundationVersionNumber_iOS_7_0 +#define kCFCoreFoundationVersionNumber_iOS_7_0 847.2 +#endif -#define kMarginToDrawInside (kBadgeStrokeWidth * 2) + if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) + { + // If your app is running in legacy mode, tintColor will be nil - else it must be set to some color. + if (UIApplication.sharedApplication.keyWindow) + { + isUIKitFlatMode = [UIApplication.sharedApplication.keyWindow performSelector:@selector(tintColor)] != nil; + } + else + { + // Possible that we're called early on (e.g. when used in a Storyboard). Adapt and use a temporary window. + isUIKitFlatMode = [[[UIWindow alloc] init] performSelector:@selector(tintColor)] != nil; + } + } + }); -#define kShadowOffset CGSizeMake(0.0f, 3.0f) -#define kShadowOpacity 0.4f -#define kDefaultShadowColor [UIColor colorWithWhite:0.0f alpha:kShadowOpacity] -#define kShadowRadius 1.0f + return isUIKitFlatMode; +} -#define kBadgeHeight 16.0f -#define kBadgeTextSideMargin 8.0f +@implementation JSBadgeView -#define kBadgeCornerRadius 10.0f ++ (void)applyCommonStyle +{ + JSBadgeView *badgeViewAppearanceProxy = JSBadgeView.appearance; -#define kDefaultBadgeAlignment JSBadgeViewAlignmentTopRight + badgeViewAppearanceProxy.backgroundColor = UIColor.clearColor; + badgeViewAppearanceProxy.badgeAlignment = JSBadgeViewAlignmentTopRight; + badgeViewAppearanceProxy.badgeBackgroundColor = UIColor.redColor; + badgeViewAppearanceProxy.badgeTextFont = [UIFont boldSystemFontOfSize:UIFont.systemFontSize]; + badgeViewAppearanceProxy.badgeTextColor = UIColor.whiteColor; +} -@implementation JSBadgeView ++ (void)applyLegacyStyle +{ + JSBadgeView *badgeViewAppearanceProxy = JSBadgeView.appearance; + + badgeViewAppearanceProxy.badgeOverlayColor = [UIColor colorWithWhite:1.0f alpha:0.3]; + badgeViewAppearanceProxy.badgeTextShadowColor = UIColor.clearColor; + badgeViewAppearanceProxy.badgeShadowColor = [UIColor colorWithWhite:0.0f alpha:0.4f]; + badgeViewAppearanceProxy.badgeShadowSize = CGSizeMake(0.0f, 3.0f); + badgeViewAppearanceProxy.badgeStrokeWidth = 2.0f; + badgeViewAppearanceProxy.badgeStrokeColor = UIColor.whiteColor; +} -- (void)awakeFromNib ++ (void)applyIOS7Style { - [super awakeFromNib]; + JSBadgeView *badgeViewAppearanceProxy = JSBadgeView.appearance; - [self _init]; + badgeViewAppearanceProxy.badgeOverlayColor = UIColor.clearColor; + badgeViewAppearanceProxy.badgeTextShadowColor = UIColor.clearColor; + badgeViewAppearanceProxy.badgeShadowColor = UIColor.clearColor; + badgeViewAppearanceProxy.badgeStrokeWidth = 0.0f; + badgeViewAppearanceProxy.badgeStrokeColor = badgeViewAppearanceProxy.badgeBackgroundColor; } -- (id)initWithFrame:(CGRect)frame ++ (void)initialize { - if ((self = [super initWithFrame:frame])) + if (self == JSBadgeView.class) { - [self _init]; - } + [self applyCommonStyle]; - return self; + if (JSBadgeViewIsUIKitFlatMode()) + { + [self applyIOS7Style]; + } + else + { + [self applyLegacyStyle]; + } + } } - (id)initWithParentView:(UIView *)parentView alignment:(JSBadgeViewAlignment)alignment @@ -83,23 +125,13 @@ - (id)initWithParentView:(UIView *)parentView alignment:(JSBadgeViewAlignment)al return self; } -- (void)_init -{ - self.backgroundColor = [UIColor clearColor]; - - _badgeAlignment = kDefaultBadgeAlignment; - - _badgeBackgroundColor = kDefaultBadgeBackgroundColor; - _badgeOverlayColor = kDefaultOverlayColor; - _badgeTextColor = kDefaultBadgeTextColor; - _badgeTextShadowColor = kDefaultBadgeShadowColor; - _badgeTextFont = kDefaultBadgeTextFont; - _badgeShadowColor = kDefaultBadgeShadowColor; - _badgeStrokeColor = kDefaultBadgeStrokeColor; -} - #pragma mark - Layout +- (CGFloat)marginToDrawInside +{ + return self.badgeStrokeWidth * 2.0f; +} + - (void)layoutSubviews { [super layoutSubviews]; @@ -108,9 +140,10 @@ - (void)layoutSubviews const CGRect superviewBounds = CGRectIsEmpty(_frameToPositionInRelationWith) ? self.superview.bounds : _frameToPositionInRelationWith; const CGFloat textWidth = [self sizeOfTextForCurrentSettings].width; - - const CGFloat viewWidth = textWidth + kBadgeTextSideMargin + (kMarginToDrawInside * 2); - const CGFloat viewHeight = kBadgeHeight + (kMarginToDrawInside * 2); + + const CGFloat marginToDrawInside = [self marginToDrawInside]; + const CGFloat viewWidth = textWidth + JSBadgeViewTextSideMargin + (marginToDrawInside * 2); + const CGFloat viewHeight = JSBadgeViewHeight + (marginToDrawInside * 2); const CGFloat superviewWidth = superviewBounds.size.width; const CGFloat superviewHeight = superviewBounds.size.height; @@ -250,6 +283,17 @@ - (void)setBadgeBackgroundColor:(UIColor *)badgeBackgroundColor } } +- (void)setBadgeStrokeWidth:(CGFloat)badgeStrokeWidth +{ + if (badgeStrokeWidth != _badgeStrokeWidth) + { + _badgeStrokeWidth = badgeStrokeWidth; + + [self setNeedsLayout]; + [self setNeedsDisplay]; + } +} + - (void)setBadgeStrokeColor:(UIColor *)badgeStrokeColor { if (badgeStrokeColor != _badgeStrokeColor) @@ -270,6 +314,16 @@ - (void)setBadgeShadowColor:(UIColor *)badgeShadowColor } } +- (void)setBadgeShadowSize:(CGSize)badgeShadowSize +{ + if (!CGSizeEqualToSize(badgeShadowSize, _badgeShadowSize)) + { + _badgeShadowSize = badgeShadowSize; + + [self setNeedsDisplay]; + } +} + #pragma mark - Drawing - (void)drawRect:(CGRect)rect @@ -279,10 +333,11 @@ - (void)drawRect:(CGRect)rect if (anyTextToDraw) { CGContextRef ctx = UIGraphicsGetCurrentContext(); + + const CGFloat marginToDrawInside = [self marginToDrawInside]; + const CGRect rectToDraw = CGRectInset(rect, marginToDrawInside, marginToDrawInside); - const CGRect rectToDraw = CGRectInset(rect, kMarginToDrawInside, kMarginToDrawInside); - - UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:rectToDraw byRoundingCorners:(UIRectCorner)UIRectCornerAllCorners cornerRadii:CGSizeMake(kBadgeCornerRadius, kBadgeCornerRadius)]; + UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:rectToDraw byRoundingCorners:(UIRectCorner)UIRectCornerAllCorners cornerRadii:CGSizeMake(JSBadgeViewCornerRadius, JSBadgeViewCornerRadius)]; /* Background and shadow */ CGContextSaveGState(ctx); @@ -290,7 +345,7 @@ - (void)drawRect:(CGRect)rect CGContextAddPath(ctx, borderPath.CGPath); CGContextSetFillColorWithColor(ctx, self.badgeBackgroundColor.CGColor); - CGContextSetShadowWithColor(ctx, kShadowOffset, kShadowRadius, self.badgeShadowColor.CGColor); + CGContextSetShadowWithColor(ctx, self.badgeShadowSize, JSBadgeViewShadowRadius, self.badgeShadowColor.CGColor); CGContextDrawPath(ctx, kCGPathFill); } @@ -327,7 +382,7 @@ - (void)drawRect:(CGRect)rect { CGContextAddPath(ctx, borderPath.CGPath); - CGContextSetLineWidth(ctx, kBadgeStrokeWidth); + CGContextSetLineWidth(ctx, self.badgeStrokeWidth); CGContextSetStrokeColorWithColor(ctx, self.badgeStrokeColor.CGColor); CGContextDrawPath(ctx, kCGPathStroke); From 313a2235c4cf10fe498ed607f2bb973be202a596 Mon Sep 17 00:00:00 2001 From: Javier Soto Date: Mon, 30 Sep 2013 19:42:16 -0700 Subject: [PATCH 3/8] Bumping version to 1.3.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8df3b9e..0c7c87d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ badgeView.badgeText = @"3"; - Check the header file for all the things you can customize. ## [CocoaPods](http://cocoapods.org/): -- Add `pod 'JSBadgeView', '~> 1.2.0'` to your `Podfile`. +- Add `pod 'JSBadgeView', '~> 1.3.0'` to your `Podfile`. - You're done! ## `UIAppearance` From a223647bf2ee19a1ee836e8bd2374109282e8afc Mon Sep 17 00:00:00 2001 From: Javier Soto Date: Mon, 30 Sep 2013 19:47:01 -0700 Subject: [PATCH 4/8] iOS 7 screenshot --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c7c87d..73e1cfb 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,10 @@ Very optimized for performance: drawn entirely using CoreGraphics. +iOS 7 style: + + + ## Usage - Clone the repository: @@ -37,7 +41,7 @@ badgeView.badgeText = @"3"; - You can customize all `JSBadgeView`s in your application, or the ones that are subviews of a specific type of view, using `UIAppearance`. Example: ```objc -[[JSBadgeView appearance] setBadgeBackgroundColor:[UIColor blackColor]]; +[[JSBadgeView appearance] setBadgeBackgroundColor:UIColor.blackColor]; [[JSBadgeView appearance] setBadgeAlignment:@(JSBadgeViewAlignmentTopRight)]; ``` From ba3c744002a92777654e21f7a39188cc9ed33b48 Mon Sep 17 00:00:00 2001 From: Javier Soto Date: Mon, 30 Sep 2013 19:49:12 -0700 Subject: [PATCH 5/8] Updated image URL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 73e1cfb..9cb9a48 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Very optimized for performance: drawn entirely using CoreGraphics. iOS 7 style: - + ## Usage - Clone the repository: From 57307205acbb5abdf32d9ec7e6e8c52387dee2df Mon Sep 17 00:00:00 2001 From: Javier Soto Date: Mon, 30 Sep 2013 19:50:11 -0700 Subject: [PATCH 6/8] Fixed image MD syntax --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9cb9a48..791ea28 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Very optimized for performance: drawn entirely using CoreGraphics. iOS 7 style: - + ## Usage - Clone the repository: From 50a9c2399b3be5d7e7e5a61c1e716e9b6777e856 Mon Sep 17 00:00:00 2001 From: Javier Soto Date: Mon, 30 Sep 2013 19:52:40 -0700 Subject: [PATCH 7/8] Smaller iOS 7 image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9cb9a48..a12c108 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Very optimized for performance: drawn entirely using CoreGraphics. iOS 7 style: - + ## Usage - Clone the repository: From 0e7d0a6eb8080353d1722687aadbfb9f80dc3695 Mon Sep 17 00:00:00 2001 From: Javier Soto Date: Mon, 30 Sep 2013 19:54:16 -0700 Subject: [PATCH 8/8] Fixing syntax again --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a12c108..810c9a1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Very optimized for performance: drawn entirely using CoreGraphics. iOS 7 style: - + ## Usage - Clone the repository: