美文网首页iOS 技术分享
iOS - Button添加角标

iOS - Button添加角标

作者: Joh蜗牛 | 来源:发表于2020-10-16 18:02 被阅读0次

    1.封装一个基于Button的类,代码如下:

    .h文件
    //
    //  BadgeButton.h
    //  SteelRound
    //
    //  Created by z on 2020/10/16.
    //  Copyright © 2020 AKFH. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface BadgeButton : UIButton
    
    @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
    
    NS_ASSUME_NONNULL_END
    
    
    .m
    //
    //  BadgeButton.m
    //  SteelRound
    //
    //  Created by z on 2020/10/16.
    //  Copyright © 2020 AKFH. All rights reserved.
    //
    
    #import "BadgeButton.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 BadgeButton
    
    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    - (void)drawRect:(CGRect)rect {
        // Drawing code
    }
    */
    
    - (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
    
    
    2.调用:
    UIImage *image = [UIImage imageNamed:@"msgImg"];
        BadgeButton *button = [BadgeButton buttonWithType:(UIButtonTypeCustom)];
        button.frame = CGRectMake(0, 0, 28, 18);
        [button setImage:image forState:(UIControlStateNormal)];
        button.badgeValue = @"6";
        button.badgeBGColor = [UIColor cyanColor];
        button.badgeTextColor = [UIColor blackColor];
        button.shouldHideBadgeAtZero = YES;//角标为0时,默认隐藏
        [button addTarget:self action:@selector(change) forControlEvents:(UIControlEventTouchUpInside)];
        UIBarButtonItem *navButton = [[UIBarButtonItem alloc] initWithCustomView:button];
        self.navigationItem.leftBarButtonItem = navButton;
    

    相关文章

      网友评论

        本文标题:iOS - Button添加角标

        本文链接:https://www.haomeiwen.com/subject/nlqtmktx.html