设置button未读角标

本文介绍了如何在Objective-C中通过自定义一个名为LayoutBadgeButton的按钮类来实现未读消息角标的功能。该类包含了角标的颜色、文字、字体等属性的设置,并提供了动画效果。当角标值变化时,会自动更新角标的显示,并且当角标值为0时,可以自动隐藏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上文:https://blog.youkuaiyun.com/it_15077647703/article/details/117648122
因为项目需求要在button上添加未读角标,为了方便使用我就直接继承button图文样式自定义类来设置类
继承于ReLayoutBuuton(上文的button类)
.h文件如下
@interface LayoutBadgeButton : ReLayoutBuuton

@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

.m文件实现
#import “LayoutBadgeButton.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 LayoutBadgeButton

  • (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

在需要设置button角标的页面 导入头文件#import “LayoutBadgeButton.h”

LayoutBadgeButton * button = [LayoutBadgeButton buttonWithType:UIButtonTypeCustom];

button.badgeValue = [NSString stringWithFormat:@"%d",model.message];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值