Demo:https://download.csdn.net/download/u012881779/11950106
项目中看到大佬写的UIButton+Badge非常不错,这里写个demo修复了一些bug后分享下.
示意图:

#import "InfoViewController.h"
#import "UIButton+Badge.h"@interface InfoViewController ()@property (weak, nonatomic) IBOutlet UIButton *homeBut;
@property (assign, nonatomic) NSInteger num;@end@implementation InfoViewController- (void)viewDidLoad {[super viewDidLoad];
}// 点击 加|减 按钮
- (IBAction)tapAddOrSubAction:(id)sender {UIButton *tempBut = (UIButton *)sender;if (tempBut.tag == 2100) {// 减_num = _num - 1;if (_num < 0) {_num = 0;}} else if (tempBut.tag == 2101) {// 加_num = _num + 1;}[_homeBut setBadgeValue:[NSString stringWithFormat:@"%ld",(long)_num]];[self setupBadgeWithButton:_homeBut];
}// 设置标记 必须在setBadgeValue:方法之后调用,因为要先让badge初始化.
- (void)setupBadgeWithButton:(UIButton *)button {// 当角标为0时,自动去除角标button.shouldHideBadgeAtZero = YES;// 当角标的值发生变化,角标的动画是否显示button.shouldAnimateBadge = YES;// 角标的最小尺寸button.badgeMinSize = 10;// 角标的x值button.badgeOriginX = button.frame.size.width - button.badge.frame.size.width/2.0;// 角标的y值button.badgeOriginY = -7;
}@end

UIButton+Badge
因为category中不能添加属性,所以这里大佬们使用的运行时处理.

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface UIButton (Badge)@property (strong, nonatomic) UILabel *badge;/***  角标显示的信息,可以为数字和文字*/
@property (nonatomic) NSString *badgeValue;
/***  角标背景颜色,默认为红色*/
@property (nonatomic) UIColor *badgeBGColor;
/***  角标文字的颜色*/
@property (nonatomic) UIColor *badgeTextColor;
/***  角标字号*/
@property (nonatomic) UIFont *badgeFont;
/***  角标的气泡边界*/
@property (nonatomic) CGFloat badgePadding;
/***  角标的最小尺寸*/
@property (nonatomic) CGFloat badgeMinSize;
/***  角标的x值*/
@property (nonatomic) CGFloat badgeOriginX;
/***  角标的y值*/
@property (nonatomic) CGFloat badgeOriginY;
/***  当角标为0时,自动去除角标*/
@property BOOL shouldHideBadgeAtZero;
/***  当角标的值发生变化,角标的动画是否显示*/
@property BOOL shouldAnimateBadge;@end
#import "UIButton+Badge.h"
#import <objc/runtime.h>NSString const *badgeKey                 = @"badgeKey";NSString const *badgeBGColorKey          = @"badgeBGColorKey";
NSString const *badgeTextColorKey        = @"badgeTextColorKey";
NSString const *badgeFontKey             = @"badgeFontKey";
NSString const *badgePaddingKey          = @"badgePaddingKey";
NSString const *badgeMinSizeKey          = @"badgeMinSizeKey";
NSString const *badgeOriginXKey          = @"badgeOriginXKey";
NSString const *badgeOriginYKey          = @"badgeOriginYKey";
NSString const *shouldHideBadgeAtZeroKey = @"shouldHideBadgeAtZeroKey";
NSString const *shouldAnimateBadgeKey    = @"shouldAnimateBadgeKey";
NSString const *badgeValueKey            = @"badgeValueKey";@implementation UIButton (Badge)- (void)badgeInit {// 初始化,设定默认值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;// 避免角标被裁剪self.clipsToBounds = NO;
}#pragma mark - Utility methods// 当角标的属性改变时,调用此方法
- (void)refreshBadge {// 更新属性self.badge.textColor        = self.badgeTextColor;self.badge.backgroundColor  = self.badgeBGColor;self.badge.font             = self.badgeFont;
}- (CGSize)badgeExpectedSize {// 自适应角标UILabel *frameLabel = [self duplicateLabel:self.badge];[frameLabel sizeToFit];CGSize expectedLabelSize = frameLabel.frame.size;return expectedLabelSize;
}// 更新角标的frame
- (void)updateBadgeFrame {CGSize expectedLabelSize = [self badgeExpectedSize];CGFloat minHeight = expectedLabelSize.height;// 判断如果小于最小size,则为最小sizeminHeight = (minHeight < self.badgeMinSize) ? self.badgeMinSize : expectedLabelSize.height;CGFloat minWidth = expectedLabelSize.width;CGFloat padding = self.badgePadding;// 填充边界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;
}// 角标值变化
- (void)updateBadgeValueAnimated:(BOOL)animated {// 动画效果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"];}self.badge.text = self.badgeValue;// 动画时间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 {// 移除角标[UIView animateWithDuration:0.2 animations:^{// 这句代码报错 [Unknown process name] CGAffineTransformInvert: singular matrix.//self.badge.transform = CGAffineTransformMakeScale(0, 0);} completion:^(BOOL finished) {[self.badge removeFromSuperview];}];
}#pragma mark - getters/setters- (UILabel *)badge {return objc_getAssociatedObject(self, &badgeKey);
}- (void)setBadge:(UILabel *)badgeLabel {objc_setAssociatedObject(self, &badgeKey, badgeLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}// 显示角标
- (NSString *)badgeValue {return objc_getAssociatedObject(self, &badgeValueKey);
}- (void)setBadgeValue:(NSString *)badgeValue {objc_setAssociatedObject(self, &badgeValueKey, badgeValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);// 当角标信息不存在,或者为空,则移除if (!badgeValue || [badgeValue isEqualToString:@""] || [badgeValue isEqualToString:@"0"]) {[self removeBadge];} else if (!self.badge) {// 当又有值时,重新设置角标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 addSubview:self.badge];[self updateBadgeValueAnimated:YES];}
}// 进行关联
- (UIColor *)badgeBGColor {return objc_getAssociatedObject(self, &badgeBGColorKey);
}// 获取关联
- (void)setBadgeBGColor:(UIColor *)badgeBGColor {objc_setAssociatedObject(self, &badgeBGColorKey, badgeBGColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);if (self.badge) {[self refreshBadge];}
}- (UIColor *) badgeTextColor {return objc_getAssociatedObject(self, &badgeTextColorKey);
}- (void)setBadgeTextColor:(UIColor *)badgeTextColor {objc_setAssociatedObject(self, &badgeTextColorKey, badgeTextColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);if (self.badge) {[self refreshBadge];}
}- (UIFont *)badgeFont {return objc_getAssociatedObject(self, &badgeFontKey);
}-(void)setBadgeFont:(UIFont *)badgeFont {objc_setAssociatedObject(self, &badgeFontKey, badgeFont, OBJC_ASSOCIATION_RETAIN_NONATOMIC);if (self.badge) {[self refreshBadge];}
}- (CGFloat)badgePadding {NSNumber *number = objc_getAssociatedObject(self, &badgePaddingKey);return number.floatValue;
}- (void)setBadgePadding:(CGFloat)badgePadding {NSNumber *number = [NSNumber numberWithDouble:badgePadding];objc_setAssociatedObject(self, &badgePaddingKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);if (self.badge) {[self updateBadgeFrame];}
}- (CGFloat)badgeMinSize {NSNumber *number = objc_getAssociatedObject(self, &badgeMinSizeKey);return number.floatValue;
}- (void)setBadgeMinSize:(CGFloat)badgeMinSize {NSNumber *number = [NSNumber numberWithDouble:badgeMinSize];objc_setAssociatedObject(self, &badgeMinSizeKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);if (self.badge) {[self updateBadgeFrame];}
}- (CGFloat)badgeOriginX {NSNumber *number = objc_getAssociatedObject(self, &badgeOriginXKey);return number.floatValue;
}- (void)setBadgeOriginX:(CGFloat)badgeOriginX {NSNumber *number = [NSNumber numberWithDouble:badgeOriginX];objc_setAssociatedObject(self, &badgeOriginXKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);if (self.badge) {[self updateBadgeFrame];}
}- (CGFloat)badgeOriginY {NSNumber *number = objc_getAssociatedObject(self, &badgeOriginYKey);return number.floatValue;
}- (void)setBadgeOriginY:(CGFloat)badgeOriginY {NSNumber *number = [NSNumber numberWithDouble:badgeOriginY];objc_setAssociatedObject(self, &badgeOriginYKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);if (self.badge) {[self updateBadgeFrame];}
}- (BOOL)shouldHideBadgeAtZero {NSNumber *number = objc_getAssociatedObject(self, &shouldHideBadgeAtZeroKey);return number.boolValue;
}- (void)setShouldHideBadgeAtZero:(BOOL)shouldHideBadgeAtZero {NSNumber *number = [NSNumber numberWithBool:shouldHideBadgeAtZero];objc_setAssociatedObject(self, &shouldHideBadgeAtZeroKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}- (BOOL)shouldAnimateBadge {NSNumber *number = objc_getAssociatedObject(self, &shouldAnimateBadgeKey);return number.boolValue;
}- (void)setShouldAnimateBadge:(BOOL)shouldAnimateBadge {NSNumber *number = [NSNumber numberWithBool:shouldAnimateBadge];objc_setAssociatedObject(self, &shouldAnimateBadgeKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}@end

[iOS]UIButton+Badge相关推荐

  1. iOS UIButton 图片文字上下垂直布局 解决方案

    iOS UIButton 图片文字上下垂直布局 解决方案 参考文章: (1)iOS UIButton 图片文字上下垂直布局 解决方案 (2)https://www.cnblogs.com/yajunL ...

  2. iOS - UIButton 开发总结

    iOS - UIButton 开发总结 一 UIButton基础     iOS中提供了UIButton.UILable.UITextField.UIImageView等基础UI控件,继承于UIVie ...

  3. iOS UIButton根据内容自动布局

    级别: ★☆☆☆☆ 标签:「iOS」「UIButton」「自动布局」 作者: 沐灵洛 审校: QiShare团队 UIButton是开发过程中最常用的控件,可以设置各种样式,也可以自定义添加图片.标题 ...

  4. iOS UIButton文字和图片间距随意调整

    代码地址如下: http://www.demodashi.com/demo/11606.html 前记 在开发中,我们经常会遇到这么一种情况,就是一个按钮上面有图片也有文字,但是往往设计并不是我们想要 ...

  5. iOS UIButton之UIEdgeInsets详解

    级别:★★☆☆☆ 标签:「UIButton内偏移量」「titleEdgeInsets」「imageEdgeInsets」 作者: MrLiuQ 审校: QiShare团队 我们先看一下苹果官方对UIE ...

  6. iOS UIButton放到页面底部延迟响应touchDown事件

    第1部分:说明 最近在做一个类似微信语音聊天的功能,在屏幕的底部放一个Button,按下时可以语音说话,松开时将语音发出去.但是做的过程中遇到一个坑:按钮放到页面最底部的时候会延迟touchDown事 ...

  7. iOS UIButton 文字图片上下左右布局

    例如文字在左 图片在右,iOS 9 之后一句话搞定 backBtn.semanticContentAttribute = UISemanticContentAttributeForceRightToL ...

  8. iOS UIbutton 点击无反应的几种情况

    1.UIButton不能点击情况的第一种是,你将button添加到一个不能响应点击事件的View里.如你将button添加到UIImageView中,解决办法只需将UIImageView的 userI ...

  9. iOS UIButton(按钮)

    UIButton属性 1.UIButton状态: UIControlStateNormal // 正常状态 UIControlStateHighlighted // 高亮状态 UIControlSta ...

最新文章

  1. NET Framework 2.0中的数据访问新特性
  2. 全球及中国现金回收机行业销售前景与运营效益分析报告2022版
  3. defer和async属性详解
  4. apachacxf项目使用@WebService报错
  5. 在VS Code中执行SQL查询,是怎样一种体验?
  6. LeetCode 1086. 前五科的均分(map + 优先队列)
  7. 常见的运行时异常 java 1615309080
  8. php控制器的作用,控制器定义 · ThinkPHP5.0完全开发手册 · 看云
  9. SQOOP 导出SQL SERVER中数据
  10. AI 又进阶!除了鉴别 PS 图片,还能一键卸妆!
  11. GeoHash入门及应用
  12. vmlinuz文件解压方法
  13. 台式计算机主板,主板天梯图2020 热门台式机电脑主板排行榜
  14. Knn算法之手写识别系统
  15. GB50204-2015 混凝土结构工程施工质量验收规范 免费下载
  16. MYSQL基础之浅聊 变量
  17. javaWeb新闻发布展示(分页)
  18. 用html简单做一个课程表。
  19. 遗传基因科普(5):DNA双螺旋结构的发现
  20. 基于单片机的多功能电子医药盒设计

热门文章

  1. linux 正规表达式 文件格式处理
  2. c语言之strchr函数
  3. Android移除原生内置应用
  4. 【JD算法题】定义一个数组的权值为,该数组最大值的出现次数。求长度为n且每个元素范围都在[1,n]的所有数组的权值之和。
  5. EXCEL 批量生成sheet表+生成超链接目录+某列按多条件去重罗列+提取单元格中的字母、数字
  6. linux系统下批量解压方法汇总
  7. 2DPSK调制解调matlab,2DPSK调制与解调-matlab
  8. 数据库SQL优化:百万级数据优化
  9. U盘内存缩小了如何回复
  10. 蓝桥杯嵌入式组 历年客观题解析