Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I add tiny mode and backgroudimage for the JSBadgeView #54

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,31 @@
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
Expand Down Expand Up @@ -50,4 +65,4 @@
"version" : 1,
"author" : "xcode"
}
}
}
6 changes: 4 additions & 2 deletions Example/JSBadgeView/JSViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#import <QuartzCore/QuartzCore.h>

#define kNumBadges 100
#define kNumBadges 120

#define kViewBackgroundColor [UIColor colorWithRed:0.357 green:0.757 blue:0.357 alpha:1]

Expand Down Expand Up @@ -76,7 +76,9 @@ - (void)loadView

JSBadgeView *badgeView = [[JSBadgeView alloc] initWithParentView:rectangle alignment:JSBadgeViewAlignmentTopRight];
badgeView.badgeText = [NSString stringWithFormat:@"%d", i];

if (i >= 100) {
badgeView.tinyMode = YES;
}
[scrollView addSubview:rectangle];
[scrollView sendSubviewToBack:rectangle];

Expand Down
8 changes: 4 additions & 4 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PODS:
- Expecta (1.0.6)
- JSBadgeView (1.4.1)
- JSBadgeView (2.0.0)
- Specta (1.0.7)

DEPENDENCIES:
Expand All @@ -9,7 +9,7 @@ DEPENDENCIES:
- Specta

SPEC REPOS:
https://github.com/CocoaPods/Specs.git:
https://github.com/cocoapods/specs.git:
- Expecta
- Specta

Expand All @@ -19,9 +19,9 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5
JSBadgeView: 67b15e14438b19adc40ddc016d36b07016a68044
JSBadgeView: 3dbfbaf6c580f5f8dc8d1283d826c94f2041b7c5
Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66

PODFILE CHECKSUM: c814e0cbf7cb16d7dab3042bf5dc39c9d36b0d13

COCOAPODS: 1.5.0
COCOAPODS: 1.5.3
36 changes: 36 additions & 0 deletions Pod/Classes/JSBadgeView.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,42 @@ typedef NS_ENUM(NSUInteger, JSBadgeViewAlignment)
*/
@property (nonatomic, assign) CGFloat badgeMinWidth UI_APPEARANCE_SELECTOR;

/**
* The margin add to the text left and right,both left and right use badgeViewTextSideMargin/2.
*/
@property (nonatomic,assign) CGFloat badgeViewTextSideMargin UI_APPEARANCE_SELECTOR;

/**
* The corner radius use to the display rect.
*/
@property (nonatomic,assign) CGFloat badgeViewCornerRadius UI_APPEARANCE_SELECTOR;

/**
* The height for the hold rect of text.
*/
@property (nonatomic,assign) CGFloat badgeViewHeight UI_APPEARANCE_SELECTOR;
/**
* shadow radius, if it > 0, we will draw a shadow.
*/
@property (nonatomic,assign) CGFloat badgeViewShadowRadius UI_APPEARANCE_SELECTOR;
/**
* will you prefer a backgroud image? it will auto scale to fit the badge size with the same radio.
*/
@property (nonatomic,strong) UIImage* badgeBackgroundImage UI_APPEARANCE_SELECTOR;
/**
* tiny mode,not show text,just a small cire.
*/
@property (nonatomic,assign) BOOL tinyMode UI_APPEARANCE_SELECTOR;
/**
* tiny mode's backgroud color.
*/
@property (nonatomic,strong) UIColor* tinyModeBackgroundColor UI_APPEARANCE_SELECTOR;

/**
* tiny mode's radius.
*/
@property (nonatomic,assign) CGFloat badgeViewTinyRadius UI_APPEARANCE_SELECTOR;

/**
* Optionally init using this method to have the badge automatically added to another view.
*/
Expand Down
111 changes: 91 additions & 20 deletions Pod/Classes/JSBadgeView.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ + (void)applyStyle
badgeViewAppearanceProxy.badgeShadowColor = UIColor.clearColor;
badgeViewAppearanceProxy.badgeStrokeWidth = 0.0f;
badgeViewAppearanceProxy.badgeStrokeColor = badgeViewAppearanceProxy.badgeBackgroundColor;

badgeViewAppearanceProxy.badgeViewShadowRadius = 1.0f;
badgeViewAppearanceProxy.badgeViewHeight = 16.0f;
badgeViewAppearanceProxy.badgeViewTextSideMargin = 8.0f;
badgeViewAppearanceProxy.badgeViewCornerRadius = 10.0f;
badgeViewAppearanceProxy.tinyMode = NO;
badgeViewAppearanceProxy.tinyModeBackgroundColor = UIColor.redColor;
badgeViewAppearanceProxy.badgeViewTinyRadius = 5.0f;

}

+ (void)initialize
Expand All @@ -84,6 +93,21 @@ - (id)initWithParentView:(UIView *)parentView alignment:(JSBadgeViewAlignment)al
return self;
}

-(void) setTinyMode:(BOOL)tinyMode
{
if ( tinyMode == self.tinyMode) {
return;
}
_tinyMode = tinyMode;
[self setNeedsLayout];
}

-(void)setBadgeBackgroundImage:(UIImage *)badgeBackgroundImage
{
_badgeBackgroundImage = badgeBackgroundImage;
[self setNeedsLayout];
}

#pragma mark - Layout

- (CGFloat)marginToDrawInside
Expand All @@ -94,19 +118,25 @@ - (CGFloat)marginToDrawInside
- (void)layoutSubviews
{
[super layoutSubviews];



CGRect newFrame = self.frame;
const CGRect superviewBounds = CGRectIsEmpty(_frameToPositionInRelationWith) ? self.superview.bounds : _frameToPositionInRelationWith;
const CGRect superviewBounds = CGRectIsEmpty(self.frameToPositionInRelationWith) ? self.superview.bounds : self.frameToPositionInRelationWith;

const CGFloat textWidth = [self sizeOfTextForCurrentSettings].width;

const CGFloat marginToDrawInside = [self marginToDrawInside];
const CGFloat viewWidth = MAX(_badgeMinWidth, textWidth + JSBadgeViewTextSideMargin + (marginToDrawInside * 2));
const CGFloat viewHeight = JSBadgeViewHeight + (marginToDrawInside * 2);
CGFloat viewWidth = MAX(self.badgeMinWidth, textWidth + self.badgeViewTextSideMargin + (marginToDrawInside * 2));
CGFloat viewHeight = self.badgeViewHeight + (marginToDrawInside * 2);

const CGFloat superviewWidth = superviewBounds.size.width;
const CGFloat superviewHeight = superviewBounds.size.height;

if (self.tinyMode) {
viewWidth = 2*self.badgeViewTinyRadius;
viewHeight = viewWidth;
}

newFrame.size.width = MAX(viewWidth, viewHeight);
newFrame.size.height = viewHeight;

Expand Down Expand Up @@ -301,19 +331,51 @@ - (void)drawRect:(CGRect)rect
const CGFloat marginToDrawInside = [self marginToDrawInside];
const CGRect rectToDraw = CGRectInset(rect, marginToDrawInside, marginToDrawInside);

UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:rectToDraw byRoundingCorners:(UIRectCorner)UIRectCornerAllCorners cornerRadii:CGSizeMake(JSBadgeViewCornerRadius, JSBadgeViewCornerRadius)];
UIBezierPath *borderPath;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before adding all these new features to the API, I believe this implementation would need to simplify. This class used -drawRect: back when it was doing complicated shadows and gradients. Now that it only supports "flat UI", there's no reason to continue doing this. Adding all this code just further complicates this implementation.
Given that I don't really have time to maintain this library, I will push back on these changes for that reason. I will however appreciate re-doing this view with AutoLayout, and without drawing with CoreGraphics instead.

if (self.tinyMode) {
borderPath= [UIBezierPath bezierPathWithRoundedRect:rectToDraw byRoundingCorners:(UIRectCorner)UIRectCornerAllCorners cornerRadii:CGSizeMake(self.badgeViewTinyRadius+marginToDrawInside, self.badgeViewTinyRadius+marginToDrawInside)];
}
else{
borderPath= [UIBezierPath bezierPathWithRoundedRect:rectToDraw byRoundingCorners:(UIRectCorner)UIRectCornerAllCorners cornerRadii:CGSizeMake(self.badgeViewCornerRadius, self.badgeViewCornerRadius)];
}
CGColorRef bgCGColor = self.tinyMode ? self.tinyModeBackgroundColor.CGColor : self.badgeBackgroundColor.CGColor;

/* Background and shadow */
CGContextSaveGState(ctx);
{
CGContextAddPath(ctx, borderPath.CGPath);
if (nil == self.badgeBackgroundImage) {
CGContextSetFillColorWithColor(ctx, bgCGColor);
/* Background and shadow */
CGContextSaveGState(ctx);
{
CGContextAddPath(ctx, borderPath.CGPath);
if (!self.tinyMode && self.badgeViewShadowRadius > 0 ) {
CGContextSetShadowWithColor(ctx, self.badgeShadowSize, self.badgeViewShadowRadius, self.badgeShadowColor.CGColor);
}

CGContextDrawPath(ctx, kCGPathFill);
}
CGContextRestoreGState(ctx);

}
else{

CGFloat width = self.badgeBackgroundImage.size.width;
CGFloat height = self.badgeBackgroundImage.size.height;

float verticalRadio = rectToDraw.size.height*1.0/height;
float horizontalRadio = rectToDraw.size.width*1.0/width;

CGContextSetFillColorWithColor(ctx, self.badgeBackgroundColor.CGColor);
CGContextSetShadowWithColor(ctx, self.badgeShadowSize, JSBadgeViewShadowRadius, self.badgeShadowColor.CGColor);
float radio = 1;
radio = verticalRadio < horizontalRadio ? horizontalRadio : verticalRadio;

CGRect displayRect = CGRectMake((rectToDraw.size.width - width*radio)/2.0f,
(rectToDraw.size.height-height*radio)/2.0f,
width*radio,
height*radio);

[self.badgeBackgroundImage drawInRect:displayRect];

CGContextDrawPath(ctx, kCGPathFill);
}
CGContextRestoreGState(ctx);



const BOOL colorForOverlayPresent = self.badgeOverlayColor && ![self.badgeOverlayColor isEqual:[UIColor clearColor]];

Expand Down Expand Up @@ -353,25 +415,34 @@ - (void)drawRect:(CGRect)rect
}
CGContextRestoreGState(ctx);

if (self.tinyMode) {
return;
}
/* Text */

CGContextSaveGState(ctx);
{
CGContextSetFillColorWithColor(ctx, self.badgeTextColor.CGColor);
CGContextSetShadowWithColor(ctx, self.badgeTextShadowOffset, 1.0, self.badgeTextShadowColor.CGColor);
if (self.badgeViewShadowRadius > 0) {
CGContextSetShadowWithColor(ctx, self.badgeTextShadowOffset, 1.0, self.badgeTextShadowColor.CGColor);
}

CGRect textFrame = rectToDraw;
const CGSize textSize = [self sizeOfTextForCurrentSettings];

textFrame.size.height = textSize.height;
textFrame.origin.y = rectToDraw.origin.y + floorf((rectToDraw.size.height - textFrame.size.height) / 2.0f);

textFrame.origin.y = rectToDraw.origin.y + ceilf((rectToDraw.size.height - textFrame.size.height) / 2.0f);

NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
textStyle.lineBreakMode = NSLineBreakByClipping;
textStyle.alignment = NSTextAlignmentCenter;

JSBadgeViewSilenceDeprecatedMethodStart();
[self.badgeText drawInRect:textFrame
withFont:self.badgeTextFont
lineBreakMode:NSLineBreakByClipping
alignment:NSTextAlignmentCenter];
withAttributes:@{NSFontAttributeName:self.badgeTextFont,
NSParagraphStyleAttributeName: textStyle}];
JSBadgeViewSilenceDeprecatedMethodEnd();

}
CGContextRestoreGState(ctx);
}
Expand Down