app内部角标的需求可以说是随处可见,今天就写了一个Button的角标类,方便以后调用,此处做记录使用,有需要的旁友,可以直接copy后食用。
废话不多说,直接上代码。
//
// 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
最后附上效果图片,哇咔咔,跑路。