iOS ● 导航栏按钮小角标

作者: MyiOS | 来源:发表于2016-11-03 16:46 被阅读306次
    效果图
        导入头文件 #import "UIBarButtonItem+Badge.h"
        //小角标背景颜色(默认为红色)
        self.navigationItem.leftBarButtonItem.badgeBGColor = [UIColor blueColor];
        //小角标字体颜色(默认为白色)
        self.navigationItem.leftBarButtonItem.textColor = [UIColor greenColor];
        //小角标个数 (可在网络请求成功里面给小角标赋值)
        self.navigationItem.rightBarButtonItem.badgeValue = @"7";
    

    来吧 , 开始建:

    建立完是这样滴 :

    UIBarButtonItem+Badge.h里:
    #import <UIKit/UIKit.h>
    
    @interface UIBarButtonItem (Badge)
    
    @property (strong, atomic) UILabel *badge;
    
    // Badge value to be display
    @property (nonatomic) NSString *badgeValue;
    // Badge background color
    @property (nonatomic) UIColor *badgeBGColor;
    // Badge text color
    @property (nonatomic) UIColor *badgeTextColor;
    // Badge font
    @property (nonatomic) UIFont *badgeFont;
    // Padding value for the badge
    @property (nonatomic) CGFloat badgePadding;
    // Minimum size badge to small
    @property (nonatomic) CGFloat badgeMinSize;
    // Values for offseting the badge over the BarButtonItem you picked
    @property (nonatomic) CGFloat badgeOriginX;
    @property (nonatomic) CGFloat badgeOriginY;
    // In case of numbers, remove the badge when reaching zero
    @property BOOL shouldHideBadgeAtZero;
    // Badge has a bounce animation when value changes
    @property BOOL shouldAnimateBadge;
    
    @end
    
    UIBarButtonItem+Badge.m里:
    #import <objc/runtime.h>
    #import "UIBarButtonItem+Badge.h"
    
    NSString const *UIBarButtonItem_badgeKey = @"UIBarButtonItem_badgeKey";
    
    NSString const *UIBarButtonItem_badgeBGColorKey = @"UIBarButtonItem_badgeBGColorKey";
    NSString const *UIBarButtonItem_badgeTextColorKey = @"UIBarButtonItem_badgeTextColorKey";
    NSString const *UIBarButtonItem_badgeFontKey = @"UIBarButtonItem_badgeFontKey";
    NSString const *UIBarButtonItem_badgePaddingKey = @"UIBarButtonItem_badgePaddingKey";
    NSString const *UIBarButtonItem_badgeMinSizeKey = @"UIBarButtonItem_badgeMinSizeKey";
    NSString const *UIBarButtonItem_badgeOriginXKey = @"UIBarButtonItem_badgeOriginXKey";
    NSString const *UIBarButtonItem_badgeOriginYKey = @"UIBarButtonItem_badgeOriginYKey";
    NSString const *UIBarButtonItem_shouldHideBadgeAtZeroKey = @"UIBarButtonItem_shouldHideBadgeAtZeroKey";
    NSString const *UIBarButtonItem_shouldAnimateBadgeKey = @"UIBarButtonItem_shouldAnimateBadgeKey";
    NSString const *UIBarButtonItem_badgeValueKey = @"UIBarButtonItem_badgeValueKey";
    
    @implementation UIBarButtonItem (Badge)
    
    @dynamic badgeValue, badgeBGColor, badgeTextColor, badgeFont;
    @dynamic badgePadding, badgeMinSize, badgeOriginX, badgeOriginY;
    @dynamic shouldHideBadgeAtZero, shouldAnimateBadge;
    
    - (void)badgeInit
    {
        UIView *superview = nil;
        CGFloat defaultOriginX = 0;
        if (self.customView) {
            superview = self.customView;
            defaultOriginX = superview.frame.size.width - self.badge.frame.size.width/2;
            // Avoids badge to be clipped when animating its scale
            superview.clipsToBounds = NO;
        } else if ([self respondsToSelector:@selector(view)] && [(id)self view]) {
            superview = [(id)self view];
            defaultOriginX = superview.frame.size.width - self.badge.frame.size.width;
        }
        [superview addSubview:self.badge];
        
        // Default design initialization
        self.badgeBGColor   = [UIColor redColor];
        self.badgeTextColor = [UIColor whiteColor];
        self.badgeFont      = [UIFont systemFontOfSize:9.0];
        self.badgePadding   = 6;
        self.badgeMinSize   = 8;
        self.badgeOriginX   = defaultOriginX;
        self.badgeOriginY   = -4;
        self.shouldHideBadgeAtZero = YES;
        self.shouldAnimateBadge = YES;
    }
    
    #pragma mark - Utility methods
    
    // Handle badge display when its properties have been changed (color, font, ...)
    - (void)refreshBadge
    {
        // Change new attributes
        self.badge.textColor        = self.badgeTextColor;
        self.badge.backgroundColor  = self.badgeBGColor;
        self.badge.font             = self.badgeFont;
        
        if (!self.badgeValue || [self.badgeValue isEqualToString:@""] || ([self.badgeValue isEqualToString:@"0"] && self.shouldHideBadgeAtZero)) {
            self.badge.hidden = YES;
        } else {
            self.badge.hidden = NO;
            [self updateBadgeValueAnimated:YES];
        }
        
    }
    
    - (CGSize) badgeExpectedSize
    {
        // When the value changes the badge could need to get bigger
        // Calculate expected size to fit new value
        // Use an intermediate label to get expected size thanks to sizeToFit
        // We don't call sizeToFit on the true label to avoid bad display
        UILabel *frameLabel = [self duplicateLabel:self.badge];
        [frameLabel sizeToFit];
        
        CGSize expectedLabelSize = frameLabel.frame.size;
        return expectedLabelSize;
    }
    
    - (void)updateBadgeFrame
    {
        
        CGSize expectedLabelSize = [self badgeExpectedSize];
        
        // Make sure that for small value, the badge will be big enough
        CGFloat minHeight = expectedLabelSize.height;
        
        // Using a const we make sure the badge respect the minimum size
        minHeight = (minHeight < self.badgeMinSize) ? self.badgeMinSize : expectedLabelSize.height;
        CGFloat minWidth = expectedLabelSize.width;
        CGFloat padding = self.badgePadding;
        
        // Using const we make sure the badge doesn't get too smal
        minWidth = (minWidth < minHeight) ? minHeight : expectedLabelSize.width;
        self.badge.layer.masksToBounds = YES;
        // 角标的位置
        self.badge.frame = CGRectMake(self.badgeOriginX+3, self.badgeOriginY-3, minWidth + padding, minHeight + padding);
        self.badge.layer.cornerRadius = (minHeight + padding) / 2;
    }
    
    // Handle the badge changing value
    - (void)updateBadgeValueAnimated:(BOOL)animated
    {
        // Bounce animation on badge if value changed and if animation authorized
        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"];
        }
        
        // Set the new value
        self.badge.text = self.badgeValue;
        
        // Animate the size modification if needed
        if (animated && self.shouldAnimateBadge) {
            [UIView animateWithDuration:0.2 animations:^{
                [self updateBadgeFrame];
            }];
        } else {
            [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
    {
        // Animate badge removal
        [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 {
        UILabel* lbl = objc_getAssociatedObject(self, &UIBarButtonItem_badgeKey);
        if(lbl==nil) {
            lbl = [[UILabel alloc] initWithFrame:CGRectMake(self.badgeOriginX, self.badgeOriginY, 20, 20)];
            [self setBadge:lbl];
            [self badgeInit];
            [self.customView addSubview:lbl];
            lbl.textAlignment = NSTextAlignmentCenter;
        }
        return lbl;
    }
    -(void)setBadge:(UILabel *)badgeLabel
    {
        objc_setAssociatedObject(self, &UIBarButtonItem_badgeKey, badgeLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    // Badge value to be display
    -(NSString *)badgeValue {
        return objc_getAssociatedObject(self, &UIBarButtonItem_badgeValueKey);
    }
    -(void) setBadgeValue:(NSString *)badgeValue
    {
        objc_setAssociatedObject(self, &UIBarButtonItem_badgeValueKey, badgeValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        
        // When changing the badge value check if we need to remove the badge
        [self updateBadgeValueAnimated:YES];
        [self refreshBadge];
    }
    
    // Badge background color
    -(UIColor *)badgeBGColor {
        return objc_getAssociatedObject(self, &UIBarButtonItem_badgeBGColorKey);
    }
    -(void)setBadgeBGColor:(UIColor *)badgeBGColor
    {
        objc_setAssociatedObject(self, &UIBarButtonItem_badgeBGColorKey, badgeBGColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if (self.badge) {
            [self refreshBadge];
        }
    }
    
    // Badge text color
    -(UIColor *)badgeTextColor {
        return objc_getAssociatedObject(self, &UIBarButtonItem_badgeTextColorKey);
    }
    -(void)setBadgeTextColor:(UIColor *)badgeTextColor
    {
        objc_setAssociatedObject(self, &UIBarButtonItem_badgeTextColorKey, badgeTextColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if (self.badge) {
            [self refreshBadge];
        }
    }
    
    // Badge font
    -(UIFont *)badgeFont {
        return objc_getAssociatedObject(self, &UIBarButtonItem_badgeFontKey);
    }
    -(void)setBadgeFont:(UIFont *)badgeFont
    {
        objc_setAssociatedObject(self, &UIBarButtonItem_badgeFontKey, badgeFont, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if (self.badge) {
            [self refreshBadge];
        }
    }
    
    // Padding value for the badge
    -(CGFloat) badgePadding {
        NSNumber *number = objc_getAssociatedObject(self, &UIBarButtonItem_badgePaddingKey);
        return number.floatValue;
    }
    -(void) setBadgePadding:(CGFloat)badgePadding
    {
        NSNumber *number = [NSNumber numberWithDouble:badgePadding];
        objc_setAssociatedObject(self, &UIBarButtonItem_badgePaddingKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if (self.badge) {
            [self updateBadgeFrame];
        }
    }
    
    // Minimum size badge to small
    -(CGFloat) badgeMinSize {
        NSNumber *number = objc_getAssociatedObject(self, &UIBarButtonItem_badgeMinSizeKey);
        return number.floatValue;
    }
    -(void) setBadgeMinSize:(CGFloat)badgeMinSize
    {
        NSNumber *number = [NSNumber numberWithDouble:badgeMinSize];
        objc_setAssociatedObject(self, &UIBarButtonItem_badgeMinSizeKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if (self.badge) {
            [self updateBadgeFrame];
        }
    }
    
    // Values for offseting the badge over the BarButtonItem you picked
    -(CGFloat) badgeOriginX {
        NSNumber *number = objc_getAssociatedObject(self, &UIBarButtonItem_badgeOriginXKey);
        return number.floatValue;
    }
    -(void) setBadgeOriginX:(CGFloat)badgeOriginX
    {
        NSNumber *number = [NSNumber numberWithDouble:badgeOriginX];
        objc_setAssociatedObject(self, &UIBarButtonItem_badgeOriginXKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if (self.badge) {
            [self updateBadgeFrame];
        }
    }
    
    -(CGFloat) badgeOriginY {
        NSNumber *number = objc_getAssociatedObject(self, &UIBarButtonItem_badgeOriginYKey);
        return number.floatValue;
    }
    -(void) setBadgeOriginY:(CGFloat)badgeOriginY
    {
        NSNumber *number = [NSNumber numberWithDouble:badgeOriginY];
        objc_setAssociatedObject(self, &UIBarButtonItem_badgeOriginYKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if (self.badge) {
            [self updateBadgeFrame];
        }
    }
    
    // In case of numbers, remove the badge when reaching zero
    -(BOOL) shouldHideBadgeAtZero {
        NSNumber *number = objc_getAssociatedObject(self, &UIBarButtonItem_shouldHideBadgeAtZeroKey);
        return number.boolValue;
    }
    - (void)setShouldHideBadgeAtZero:(BOOL)shouldHideBadgeAtZero
    {
        NSNumber *number = [NSNumber numberWithBool:shouldHideBadgeAtZero];
        objc_setAssociatedObject(self, &UIBarButtonItem_shouldHideBadgeAtZeroKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if(self.badge) {
            [self refreshBadge];
        }
    }
    
    // Badge has a bounce animation when value changes
    -(BOOL) shouldAnimateBadge {
        NSNumber *number = objc_getAssociatedObject(self, &UIBarButtonItem_shouldAnimateBadgeKey);
        return number.boolValue;
    }
    - (void)setShouldAnimateBadge:(BOOL)shouldAnimateBadge
    {
        NSNumber *number = [NSNumber numberWithBool:shouldAnimateBadge];
        objc_setAssociatedObject(self, &UIBarButtonItem_shouldAnimateBadgeKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if(self.badge) {
            [self refreshBadge];
        }
    }
    
    @end
    

    运行一下 , Yeah !

    相关文章

      网友评论

        本文标题:iOS ● 导航栏按钮小角标

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