iOS 实现UIButton加小红点

来源:互联网 发布:淘客网站源码建立 编辑:程序博客网 时间:2024/06/11 06:58

因为项目有一个很简单的需求,就是如下图所示。


在一个UIButton控件上添加BadgeValue。

在网上找了一些方法,有一个我试用后简单好用的做一个笔记,同时分享给大家~

UIButton+Badge.h

#import <UIKit/UIKit.h>@interface UIButton (Badge)@property (strong, nonatomic) UILabel *badge;// Badge value to be display@property (nonatomic) NSString *badgeValue;// Badge background color@property (nonatomic) UIColor *badgeBGColor;// Badge text color@property (nonatomic) UIColor *badgeTextColor;// Badge font@property (nonatomic) UIFont *badgeFont;// Padding value for the badge@property (nonatomic) CGFloat badgePadding;// Minimum size badge to small@property (nonatomic) CGFloat badgeMinSize;// Values for offseting the badge over the BarButtonItem you picked@property (nonatomic) CGFloat badgeOriginX;@property (nonatomic) CGFloat badgeOriginY;// In case of numbers, remove the badge when reaching zero@property BOOL shouldHideBadgeAtZero;// Badge has a bounce animation when value changes@property BOOL shouldAnimateBadge;@end


UIButton+Badge.m

#import <objc/runtime.h>#import "UIButton+Badge.h"NSString const *UIButton_badgeKey = @"UIButton_badgeKey";NSString const *UIButton_badgeBGColorKey = @"UIButton_badgeBGColorKey";NSString const *UIButton_badgeTextColorKey = @"UIButton_badgeTextColorKey";NSString const *UIButton_badgeFontKey = @"UIButton_badgeFontKey";NSString const *UIButton_badgePaddingKey = @"UIButton_badgePaddingKey";NSString const *UIButton_badgeMinSizeKey = @"UIButton_badgeMinSizeKey";NSString const *UIButton_badgeOriginXKey = @"UIButton_badgeOriginXKey";NSString const *UIButton_badgeOriginYKey = @"UIButton_badgeOriginYKey";NSString const *UIButton_shouldHideBadgeAtZeroKey = @"UIButton_shouldHideBadgeAtZeroKey";NSString const *UIButton_shouldAnimateBadgeKey = @"UIButton_shouldAnimateBadgeKey";NSString const *UIButton_badgeValueKey = @"UIButton_badgeValueKey";@implementation UIButton (Badge)@dynamic badgeValue, badgeBGColor, badgeTextColor, badgeFont;@dynamic badgePadding, badgeMinSize, badgeOriginX, badgeOriginY;@dynamic shouldHideBadgeAtZero, shouldAnimateBadge;- (void)badgeInit{    // Default design initialization    self.badgeBGColor   = [UIColor redColor];    self.badgeTextColor = [UIColor whiteColor];    self.badgeFont      = [UIFont systemFontOfSize:12.0];    self.badgePadding   = 6;    self.badgeMinSize   = 8;    self.badgeOriginX   = self.frame.size.width - self.badge.frame.size.width/2;    self.badgeOriginY   = -4;    self.shouldHideBadgeAtZero = YES;    self.shouldAnimateBadge = YES;    // Avoids badge to be clipped when animating its scale    self.clipsToBounds = NO;}#pragma mark - Utility methods// Handle badge display when its properties have been changed (color, font, ...)- (void)refreshBadge{    // Change new attributes    self.badge.textColor        = self.badgeTextColor;    self.badge.backgroundColor  = self.badgeBGColor;    self.badge.font             = self.badgeFont;}- (CGSize) badgeExpectedSize{    // When the value changes the badge could need to get bigger    // Calculate expected size to fit new value    // Use an intermediate label to get expected size thanks to sizeToFit    // We don't call sizeToFit on the true label to avoid bad display    UILabel *frameLabel = [self duplicateLabel:self.badge];    [frameLabel sizeToFit];        CGSize expectedLabelSize = frameLabel.frame.size;    return expectedLabelSize;}- (void)updateBadgeFrame{    CGSize expectedLabelSize = [self badgeExpectedSize];        // Make sure that for small value, the badge will be big enough    CGFloat minHeight = expectedLabelSize.height;        // Using a const we make sure the badge respect the minimum size    minHeight = (minHeight < self.badgeMinSize) ? self.badgeMinSize : expectedLabelSize.height;    CGFloat minWidth = expectedLabelSize.width;    CGFloat padding = self.badgePadding;        // Using const we make sure the badge doesn't get too smal    minWidth = (minWidth < minHeight) ? minHeight : expectedLabelSize.width;    self.badge.frame = CGRectMake(self.badgeOriginX, self.badgeOriginY, minWidth + padding, minHeight + padding);    self.badge.layer.cornerRadius = (minHeight + padding) / 2;    self.badge.layer.masksToBounds = YES;}// Handle the badge changing value- (void)updateBadgeValueAnimated:(BOOL)animated{    // Bounce animation on badge if value changed and if animation authorized    if (animated && self.shouldAnimateBadge && ![self.badge.text isEqualToString:self.badgeValue]) {        CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];        [animation setFromValue:[NSNumber numberWithFloat:1.5]];        [animation setToValue:[NSNumber numberWithFloat:1]];        [animation setDuration:0.2];        [animation setTimingFunction:[CAMediaTimingFunction functionWithControlPoints:.4f :1.3f :1.f :1.f]];        [self.badge.layer addAnimation:animation forKey:@"bounceAnimation"];    }        // Set the new value    self.badge.text = self.badgeValue;        // Animate the size modification if needed    NSTimeInterval duration = animated ? 0.2 : 0;    [UIView animateWithDuration:duration animations:^{        [self updateBadgeFrame];    }];}- (UILabel *)duplicateLabel:(UILabel *)labelToCopy{    UILabel *duplicateLabel = [[UILabel alloc] initWithFrame:labelToCopy.frame];    duplicateLabel.text = labelToCopy.text;    duplicateLabel.font = labelToCopy.font;        return duplicateLabel;}- (void)removeBadge{    // Animate badge removal    [UIView animateWithDuration:0.2 animations:^{        self.badge.transform = CGAffineTransformMakeScale(0, 0);    } completion:^(BOOL finished) {        [self.badge removeFromSuperview];        self.badge = nil;    }];}#pragma mark - getters/setters-(UILabel*) badge {    return objc_getAssociatedObject(self, &UIButton_badgeKey);}-(void)setBadge:(UILabel *)badgeLabel{    objc_setAssociatedObject(self, &UIButton_badgeKey, badgeLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}// Badge value to be display-(NSString *)badgeValue {    return objc_getAssociatedObject(self, &UIButton_badgeValueKey);}-(void) setBadgeValue:(NSString *)badgeValue{    objc_setAssociatedObject(self, &UIButton_badgeValueKey, badgeValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);        // When changing the badge value check if we need to remove the badge    if (!badgeValue || [badgeValue isEqualToString:@""] || ([badgeValue isEqualToString:@"0"] && self.shouldHideBadgeAtZero)) {        [self removeBadge];    } else if (!self.badge) {        // Create a new badge because not existing        self.badge                      = [[UILabel alloc] initWithFrame:CGRectMake(self.badgeOriginX, self.badgeOriginY, 20, 20)];        self.badge.textColor            = self.badgeTextColor;        self.badge.backgroundColor      = self.badgeBGColor;        self.badge.font                 = self.badgeFont;        self.badge.textAlignment        = NSTextAlignmentCenter;        [self badgeInit];        [self addSubview:self.badge];        [self updateBadgeValueAnimated:NO];    } else {        [self updateBadgeValueAnimated:YES];    }}// Badge background color-(UIColor *)badgeBGColor {    return objc_getAssociatedObject(self, &UIButton_badgeBGColorKey);}-(void)setBadgeBGColor:(UIColor *)badgeBGColor{    objc_setAssociatedObject(self, &UIButton_badgeBGColorKey, badgeBGColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    if (self.badge) {        [self refreshBadge];    }}// Badge text color-(UIColor *)badgeTextColor {    return objc_getAssociatedObject(self, &UIButton_badgeTextColorKey);}-(void)setBadgeTextColor:(UIColor *)badgeTextColor{    objc_setAssociatedObject(self, &UIButton_badgeTextColorKey, badgeTextColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    if (self.badge) {        [self refreshBadge];    }}// Badge font-(UIFont *)badgeFont {    return objc_getAssociatedObject(self, &UIButton_badgeFontKey);}-(void)setBadgeFont:(UIFont *)badgeFont{    objc_setAssociatedObject(self, &UIButton_badgeFontKey, badgeFont, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    if (self.badge) {        [self refreshBadge];    }}// Padding value for the badge-(CGFloat) badgePadding {    NSNumber *number = objc_getAssociatedObject(self, &UIButton_badgePaddingKey);    return number.floatValue;}-(void) setBadgePadding:(CGFloat)badgePadding{    NSNumber *number = [NSNumber numberWithDouble:badgePadding];    objc_setAssociatedObject(self, &UIButton_badgePaddingKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    if (self.badge) {        [self updateBadgeFrame];    }}// Minimum size badge to small-(CGFloat) badgeMinSize {    NSNumber *number = objc_getAssociatedObject(self, &UIButton_badgeMinSizeKey);    return number.floatValue;}-(void) setBadgeMinSize:(CGFloat)badgeMinSize{    NSNumber *number = [NSNumber numberWithDouble:badgeMinSize];    objc_setAssociatedObject(self, &UIButton_badgeMinSizeKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    if (self.badge) {        [self updateBadgeFrame];    }}// Values for offseting the badge over the BarButtonItem you picked-(CGFloat) badgeOriginX {    NSNumber *number = objc_getAssociatedObject(self, &UIButton_badgeOriginXKey);    return number.floatValue;}-(void) setBadgeOriginX:(CGFloat)badgeOriginX{    NSNumber *number = [NSNumber numberWithDouble:badgeOriginX];    objc_setAssociatedObject(self, &UIButton_badgeOriginXKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    if (self.badge) {        [self updateBadgeFrame];    }}-(CGFloat) badgeOriginY {    NSNumber *number = objc_getAssociatedObject(self, &UIButton_badgeOriginYKey);    return number.floatValue;}-(void) setBadgeOriginY:(CGFloat)badgeOriginY{    NSNumber *number = [NSNumber numberWithDouble:badgeOriginY];    objc_setAssociatedObject(self, &UIButton_badgeOriginYKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    if (self.badge) {        [self updateBadgeFrame];    }}// In case of numbers, remove the badge when reaching zero-(BOOL) shouldHideBadgeAtZero {    NSNumber *number = objc_getAssociatedObject(self, &UIButton_shouldHideBadgeAtZeroKey);    return number.boolValue;}- (void)setShouldHideBadgeAtZero:(BOOL)shouldHideBadgeAtZero{    NSNumber *number = [NSNumber numberWithBool:shouldHideBadgeAtZero];    objc_setAssociatedObject(self, &UIButton_shouldHideBadgeAtZeroKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}// Badge has a bounce animation when value changes-(BOOL) shouldAnimateBadge {    NSNumber *number = objc_getAssociatedObject(self, &UIButton_shouldAnimateBadgeKey);    return number.boolValue;}- (void)setShouldAnimateBadge:(BOOL)shouldAnimateBadge{    NSNumber *number = [NSNumber numberWithBool:shouldAnimateBadge];    objc_setAssociatedObject(self, &UIButton_shouldAnimateBadgeKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end

使用方法:给UIButton的对象设置BadgeValue的值即可。

还可以设置小红点的颜色,可以成为小黄点,小绿点。


GitHub地址:https://github.com/mikeMTOL/UIBarButtonItem-Badge

感谢:http://www.jianshu.com/p/0c7fae1cadac

原创粉丝点击