[iOS]UIButton+Badge
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相关推荐
- iOS UIButton 图片文字上下垂直布局 解决方案
iOS UIButton 图片文字上下垂直布局 解决方案 参考文章: (1)iOS UIButton 图片文字上下垂直布局 解决方案 (2)https://www.cnblogs.com/yajunL ...
- iOS - UIButton 开发总结
iOS - UIButton 开发总结 一 UIButton基础 iOS中提供了UIButton.UILable.UITextField.UIImageView等基础UI控件,继承于UIVie ...
- iOS UIButton根据内容自动布局
级别: ★☆☆☆☆ 标签:「iOS」「UIButton」「自动布局」 作者: 沐灵洛 审校: QiShare团队 UIButton是开发过程中最常用的控件,可以设置各种样式,也可以自定义添加图片.标题 ...
- iOS UIButton文字和图片间距随意调整
代码地址如下: http://www.demodashi.com/demo/11606.html 前记 在开发中,我们经常会遇到这么一种情况,就是一个按钮上面有图片也有文字,但是往往设计并不是我们想要 ...
- iOS UIButton之UIEdgeInsets详解
级别:★★☆☆☆ 标签:「UIButton内偏移量」「titleEdgeInsets」「imageEdgeInsets」 作者: MrLiuQ 审校: QiShare团队 我们先看一下苹果官方对UIE ...
- iOS UIButton放到页面底部延迟响应touchDown事件
第1部分:说明 最近在做一个类似微信语音聊天的功能,在屏幕的底部放一个Button,按下时可以语音说话,松开时将语音发出去.但是做的过程中遇到一个坑:按钮放到页面最底部的时候会延迟touchDown事 ...
- iOS UIButton 文字图片上下左右布局
例如文字在左 图片在右,iOS 9 之后一句话搞定 backBtn.semanticContentAttribute = UISemanticContentAttributeForceRightToL ...
- iOS UIbutton 点击无反应的几种情况
1.UIButton不能点击情况的第一种是,你将button添加到一个不能响应点击事件的View里.如你将button添加到UIImageView中,解决办法只需将UIImageView的 userI ...
- iOS UIButton(按钮)
UIButton属性 1.UIButton状态: UIControlStateNormal // 正常状态 UIControlStateHighlighted // 高亮状态 UIControlSta ...
最新文章
- NET Framework 2.0中的数据访问新特性
- 全球及中国现金回收机行业销售前景与运营效益分析报告2022版
- defer和async属性详解
- apachacxf项目使用@WebService报错
- 在VS Code中执行SQL查询,是怎样一种体验?
- LeetCode 1086. 前五科的均分(map + 优先队列)
- 常见的运行时异常 java 1615309080
- php控制器的作用,控制器定义 · ThinkPHP5.0完全开发手册 · 看云
- SQOOP 导出SQL SERVER中数据
- AI 又进阶!除了鉴别 PS 图片,还能一键卸妆!
- GeoHash入门及应用
- vmlinuz文件解压方法
- 台式计算机主板,主板天梯图2020 热门台式机电脑主板排行榜
- Knn算法之手写识别系统
- GB50204-2015 混凝土结构工程施工质量验收规范 免费下载
- MYSQL基础之浅聊 变量
- javaWeb新闻发布展示(分页)
- 用html简单做一个课程表。
- 遗传基因科普(5):DNA双螺旋结构的发现
- 基于单片机的多功能电子医药盒设计