美文网首页开发中的生活UI进价iOS
利用runtime为导航栏UIBarButtonItem添加Ba

利用runtime为导航栏UIBarButtonItem添加Ba

作者: karthus | 来源:发表于2016-11-07 19:14 被阅读1093次

    项目需求需要在导航栏按钮上显示小红点,但按钮使用的是系统原生的UIBarbuttonItem,重写控件不太可能,于是利用category的方式为其添加红点并显示。


    红点显示效果.png

    具体实现是利用关联,首先需要 #import <objc/runtime.h>

    OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
    OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
    

    利用关联,自己书写属性的setter和getter方法,可以向category中添加属性

    NSString *const ZYBarButtonItem_badgeKey = @"ZYBarButtonItem_badgeKey";
    
    @property (strong, nonatomic) UIView *badge;
    
    - (UIView *)badge
    {
        UIView *badge = (UIView *)objc_getAssociatedObject(self, &ZYBarButtonItem_badgeKey);
        if (!badge) {
            badge = [[UIView alloc] init];
            [self setBadge:badge];
            [self initBadge];
            [self.customView addSubview:badge];
        }
        return badge;
    }
    
    - (void)setBadge:(UIView *)badge
    {
        objc_setAssociatedObject(self, &ZYBarButtonItem_badgeKey, badge, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    

    初始化badge相关属性:
    - (void)initBadge
    {
    UIView *superview = nil;

        if (self.customView) {
            superview = self.customView;
            superview.clipsToBounds = NO;
        } else if ([self respondsToSelector:@selector(view)] && [(id)self view]) {
            superview = [(id)self view];
        }
        [superview addSubview:self.badge];
    
        // 默认设置
        self.badgeColor = [UIColor redColor];
        self.badgeSize = 8;
        self.badgeOriginX = 14;
        self.badgeOriginY = 12;
        self.badge.hidden = YES;
    }
    

    在提供给外部使用的属性中,当修改了默认属性时 需要刷新界面,如修改badge颜色属性badgeColor时,在其setter方法中调用刷新方法:
    - (void)setBadgeColor:(UIColor *)badgeColor
    {
    objc_setAssociatedObject(self, &LYBarButtonItem_badgeColorKey, badgeColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.badge) {
    [self refreshBadge];
    }
    }

    刷新方法:
    - (void)refreshBadge
    {
    self.badge.frame = (CGRect){self.badgeOriginX,self.badgeOriginY,self.badgeSize,self.badgeSize};
    self.badge.backgroundColor = self.badgeColor;
    self.badge.layer.cornerRadius = self.badgeSize/2;
    }

    至此,项目需求的小红点只需要通过控制badge的显示或隐藏即可达到。若有其他需求类似显示数字,也可通过类似方法添加属性来达成。

    demo地址

    相关文章

      网友评论

      • YungFan:你好,你这个如果是直接通过 UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"tab_me_nor"] style:UIBarButtonItemStylePlain target:self action:@selector(click:)]; 是不是就不行了?
        karthus:@YungFan 谢谢反馈 电脑不在身边 我明天看一下
        YungFan:@karthus 我试了没效果
        karthus:@YungFan 可以的 你只需要引入category头文件就行了 然后调整一下badge的位置

      本文标题:利用runtime为导航栏UIBarButtonItem添加Ba

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