最近项目里有遇到给tabBarItem添加类似小红点功能,由于系统自带的小红点只能完成数字,简易红点等功能,远远不能满足产品所需的图片,颜色等,如图:
然后我试着查看了UITabBarItem,它并不继承于UIView,我想应该是它的一个属性继承的UIView,然后我试着用运行时打印了UITabBarItem的属性和方法,结果分别如下:
幸运的是,我可以清楚的看到我要的“view”和“setView”,然后我试着用kvc取出view
UIView *barButtonView= [item1 valueForKeyPath:@"view"];
NSLog(@"%@",barButtonView);
然后再打印出了barButtonView的子控件UITabBarSwappableImageView,这个view就是我需要的用于自定义小红点的view,于是我写了下面这个分类:
// UITabBar+DLBadge.h 头文件中
@property(nonatomic,assign) CGSize badgeSize; //小红点size
@property(nonatomic,strong)UIImage *badgeImage; //小红点图片
@property(nonatomic,strong)UIColor *badgeColor; //小红点颜色
//显示小红点
- (void)showBadgeOnItemIndex:(NSUInteger )index;
//隐藏小红点
- (void)hiddenRedPointOnIndex:(NSUInteger )index animation:(BOOL )animation;
@end
// UITabBar+DLBadge.m 源文件中
#define badgeTag(index) (1000 + index)
static char *kBadgeSize = "kBadgeSize";
static char *kBadgeColor = "kBadgeColor";
static char *kBadgeImage = "kBadgeImage";
@implementation UITabBar (DLBadge)
//运行时处理分类属性
- (void)setBadgeSize:(CGSize)badgeSize
{
objc_setAssociatedObject(self, &kBadgeSize,[NSValue valueWithCGSize:badgeSize], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGSize)badgeSize
{
return [objc_getAssociatedObject(self, &kBadgeSize) CGSizeValue];
}
- (void)setBadgeImage:(UIImage *)badgeImage
{
objc_setAssociatedObject(self, &kBadgeImage, badgeImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIImage *)badgeImage
{
return objc_getAssociatedObject(self, &kBadgeImage);
}
- (void)setBadgeColor:(UIColor *)badgeColor
{
objc_setAssociatedObject(self, &kBadgeColor, badgeColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIColor *)badgeColor
{
return objc_getAssociatedObject(self, &kBadgeColor);
}
//显示小红点
- (void)showBadgeOnItemIndex:(NSUInteger )index
{
//移除
[self removeRedPointOnIndex:index animation:NO];
//默认值设置
if (CGSizeEqualToSize(self.badgeSize, CGSizeZero))
{
self.badgeSize = CGSizeMake(12, 12);
}
if (!self.badgeColor)
{
self.badgeColor = [UIColor redColor];
}
//badgeView(小红点)
CGSize badgeSize = self.badgeSize;
UIView *badgeView = [[UIView alloc]init];
badgeView.backgroundColor = self.badgeColor;
badgeView.layer.cornerRadius = badgeSize.width / 2;
badgeView.tag = badgeTag(index);
//barButtonView(里面包含文字和图片)
UIView *barButtonView = [self getBarButttonViewWithIndex:index];
//(图片的imageView)
UIView *iconView = nil;
for (UIView *swappableImageView in barButtonView.subviews)
{
if ([swappableImageView isKindOfClass:[UIImageView class]])
{
iconView = swappableImageView;
break;
}
}
CGSize iconViewSize = iconView.frame.size;
badgeView.frame = CGRectMake(iconViewSize.width - badgeSize.width / 2, - badgeSize.width / 2, badgeSize.width, badgeSize.height);
//添加图片到小红点上
UIImageView *imageview = [[UIImageView alloc]initWithFrame:badgeView.bounds];
imageview.image = self.badgeImage;
if (self.badgeImage)
{
self.badgeColor = [UIColor clearColor];
}
[badgeView addSubview:imageview];
//添加小红点到系统图层上
[iconView addSubview:badgeView];
}
//隐藏小红点
- (void)hiddenRedPointOnIndex:(NSUInteger )index animation:(BOOL )animation
{
[self removeRedPointOnIndex:index animation:animation];
}
- (void)removeRedPointOnIndex:(NSUInteger )index animation:(BOOL )animation
{
//获取对应的barButtonView(里面包含文字和图片)
UIView *barButtonView = [self getBarButttonViewWithIndex:index];
for (UIView *swapView in barButtonView.subviews)
{
if ([swapView isKindOfClass:[UIImageView class]]) //遍历出图片类的uiview图层_iconView
{
for (UIView *view in swapView.subviews)
{
if (view.tag == badgeTag(index)) //找到了小红点
{
if (animation)
{
[UIView animateWithDuration:0.2 animations:^{
view.transform = CGAffineTransformScale(view.transform, 2, 2);
view.alpha = 0;
} completion:^(BOOL finished) {
[view removeFromSuperview];
}];
}else
{
[view removeFromSuperview];
}
}
}
}
}
}
//获取barButtonView
- (UIView *)getBarButttonViewWithIndex:(NSUInteger )index
{
UIBarButtonItem *item = (UIBarButtonItem *)[self.items objectAtIndex:index];
//通过runtime和KVC找到UIBarBottunItem的View,至于为什么是“view”,可在 viewController中使用【self test】方法进行调试打印
UIView *barButtonView = [item valueForKey:@"view"];
return barButtonView;
}
引入该分类,可在控制器中直接使用,使用方法如下:
self.myTabBar.badgeSize = CGSizeMake(14, 14); //不设置默认为12
self.myTabBar.badgeColor = [UIColor orangeColor]; //不设置默认为红色
self.myTabBar.badgeImage = [UIImage imageNamed:@"补贴"]; //不设置只显示小红点
//!!!最重要的一句代码
[self.myTabBar showBadgeOnItemIndex:2]; //传入你所需要显示红点的index即可显示,此处demo点击屏幕,红点消失
demo下载地址:https://github.com/shineDongDongEr/UITabBar-DLBadge
iOS小白,行走在路上,大神路过,欢迎赐教! QQ:542155086