封装一个Button的角标类(Image等同理可以实现)
2017-04-25 14:35
232 查看
app内部角标的需求可以说是随处可见,今天就写了一个Button的角标类,方便以后调用,此处做记录使用,有需要的旁友,可以直接copy后食用。
废话不多说,直接上代码。
之后调用就十分简单
最后附上效果图片,哇咔咔,跑路。
badge.gif
废话不多说,直接上代码。
// // UIButton+Badge.h // buttonBadge // // Created by wuwj on 16/6/20. // Copyright © 2016年 wuwj. All rights reserved. // #import <UIKit/UIKit.h> @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
// // UIButton+Badge.m // buttonBadge // // Created by wuwj on 16/6/20. // Copyright © 2016年 wuwj. All rights reserved. // #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,则为最小size minHeight = (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:^{ 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, &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.shouldHideBadgeAtZero)) { [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 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
之后调用就十分简单
// // ViewController.m // buttonBadge // // Created by wuwj on 16/6/20. // Copyright © 2016年 wuwj. All rights reserved. // #import "ViewController.h" #import "UIButton+Badge.h" @interface ViewController (){ UIButton *button; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIImage *image = [UIImage imageNamed:@"mail"]; button = [UIButton buttonWithType:(UIButtonTypeCustom)]; button.frame = CGRectMake(0, 0, 28, 18); [button setImage:image forState:(UIControlStateNormal)]; button.badgeValue = @"一个信息"; button.badgeBGColor = [UIColor cyanColor]; button.badgeTextColor = [UIColor blackColor]; [button addTarget:self action:@selector(change) forControlEvents:(UIControlEventTouchUpInside)]; UIBarButtonItem *navButton = [[UIBarButtonItem alloc] initWithCustomView:button]; self.navigationItem.leftBarButtonItem = navButton; // Do any additional setup after loading the view, typically from a nib. } - (void)change{ button.badgeValue = @"两个信息"; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
最后附上效果图片,哇咔咔,跑路。
badge.gif
相关文章推荐
- Android ImageButton 如何实现一个点击效果
- iOS UIButton文字和图片上下左右偏移封装,一个方法即可实现button上文字和图片不同位置的放置
- 实现一个imagebutton, 左边为图片,右边为文字
- 有一个table表格,选中某一行后,点击“查看(button)”按钮可以实现对该行内容的显示
- Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
- 一个继承于CButton的按钮控件类,实现Button背景色与文字的共存与改变,可以自行设计背景色
- 关于实现多个button只实现可以选中一个的代码
- C#怎么通过一个按钮Button,实现点击这个按钮可以打开一个文件或者文件夹?
- 在页面中,我们经常看到,一个button按钮,如果属标点击,就会触发一个窗口的显示,如果二次点击并可以隐藏,那么如何通过JAVA配合html来实现这一功能呢?
- 有一个table表格,选中某一行后,点击“查看(button)”按钮可以实现对该行内容的显示
- 一个继承于CButton的按钮控件类,实现Button背景色与文字的共存与改变,可以自行设计背景色
- 一个Windows C++的线程类实现(封装API,形成一个类,但不完善。其实可以学习一下Delphi的TThread的写法)
- Mediator 用一个中介者对象来封装一系列的对象交互。中介者使各个对象不需要显式的相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- linux下用lex/yacc实现的一个小汇编器,for 体系实习2,实习中唯一可以拿的出来的东西
- Jbpm中Join节点修改后实现只要有一个分支到达流程就可以继续执行的效果
- 综合应用WPF/WCF/WF/LINQ之三十六:实现一个完全封装的SortableListView控件
- 一个可以实现在线用户数量查找的程序
- [c++]一个对MSXML的封装类 使用C++的Smart Pointer 对MSXML DOM封装,可以方便地访问xml文件
- [分享]新封装的一个实现无刷新连动下拉列表类
- [c++]一个对MSXML的封装类 使用C++的Smart Pointer 对MSXML DOM封装,可以方便地访问xml文件