如何在Objective-C中绘制带数字的实心彩色圆形?求更优实现方案
嘿,这个需求我之前在项目里经常碰到,完全没必要用图片叠加的方式——直接用系统控件改造或者Core Graphics绘制都更简便,还能避免图片适配的麻烦!下面给你两种实用方案:
如果只是需要简单的实心彩色圆加数字,直接用系统的UILabel或UIButton就能搞定,一行绘图代码都不用写,步骤超简单:
- 创建控件,设置合适的宽高(宽高相等才能是正圆)
- 设置背景色为你要的实心圆颜色
- 设置数字文本、字体、文字颜色
- 给控件的layer设置圆角(值为宽高的一半),并开启
clipsToBounds
示例代码:
// 创建带数字的圆形标签 UILabel *badgeLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 30, 30)]; badgeLabel.backgroundColor = [UIColor redColor]; // 实心圆颜色 badgeLabel.text = @"5"; // 显示的数字 badgeLabel.textColor = [UIColor whiteColor]; badgeLabel.textAlignment = NSTextAlignmentCenter; badgeLabel.font = [UIFont boldSystemFontOfSize:14]; // 关键:设置圆角为宽高的一半,必须开启clipsToBounds才会生效 badgeLabel.layer.cornerRadius = badgeLabel.frame.size.width / 2; badgeLabel.clipsToBounds = YES; [self.view addSubview:badgeLabel];
这个方案的优势是代码量极少、易维护,动态修改数字、颜色都只需要改对应属性就行,完全不用管图片资源的适配问题。
方案二:自定义View直接绘制(更灵活)
如果需要更复杂的效果(比如渐变背景、边框、动态调整大小适配数字长度),可以自定义一个UIView子类,用Core Graphics直接绘制。这种方式扩展性更强,适合封装成可复用的通用控件。
1. 自定义BadgeView的头文件
#import <UIKit/UIKit.h> @interface BadgeView : UIView // 可配置的属性 @property (nonatomic, copy) NSString *badgeNumber; // 显示的数字 @property (nonatomic, strong) UIColor *badgeColor; // 实心圆颜色 @property (nonatomic, strong) UIColor *textColor; // 文字颜色 @property (nonatomic, strong) UIFont *textFont; // 文字字体 @end
2. 实现文件的核心代码
#import "BadgeView.h" @implementation BadgeView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 设置默认值 self.badgeColor = [UIColor redColor]; self.textColor = [UIColor whiteColor]; self.textFont = [UIFont boldSystemFontOfSize:14]; self.backgroundColor = [UIColor clearColor]; } return self; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; // 1. 绘制实心圆形 CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, self.badgeColor.CGColor); // 以View中心为圆心,取宽高中较小值的一半作为半径,保证是正圆 CGFloat radius = MIN(rect.size.width, rect.size.height) / 2; CGContextAddArc(context, rect.size.width/2, rect.size.height/2, radius, 0, M_PI*2, YES); CGContextFillPath(context); // 2. 绘制数字文字 if (self.badgeNumber.length > 0) { NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; style.alignment = NSTextAlignmentCenter; // 文字属性配置 NSDictionary *textAttrs = @{ NSFontAttributeName: self.textFont, NSForegroundColorAttributeName: self.textColor, NSParagraphStyleAttributeName: style }; // 在View范围内居中绘制文字 [self.badgeNumber drawInRect:rect withAttributes:textAttrs]; } } // 当属性变化时,触发重绘 - (void)setBadgeNumber:(NSString *)badgeNumber { _badgeNumber = badgeNumber; [self setNeedsDisplay]; } - (void)setBadgeColor:(UIColor *)badgeColor { _badgeColor = badgeColor; [self setNeedsDisplay]; } - (void)setTextColor:(UIColor *)textColor { _textColor = textColor; [self setNeedsDisplay]; } - (void)setTextFont:(UIFont *)textFont { _textFont = textFont; [self setNeedsDisplay]; } @end
3. 使用自定义控件的示例
BadgeView *customBadge = [[BadgeView alloc] initWithFrame:CGRectMake(50, 100, 35, 35)]; customBadge.badgeNumber = @"12"; // 两位数也能完美适配 customBadge.badgeColor = [UIColor blueColor]; customBadge.textFont = [UIFont boldSystemFontOfSize:12]; [self.view addSubview:customBadge];
方案对比
- 如果你只需要基础的实心圆加数字,方案一绝对是首选,开发速度快,后期修改也方便;
- 如果需要定制化效果(比如渐变、边框、根据数字长度自动调整大小),方案二更适合,可以封装成通用控件在多个页面复用。
内容的提问来源于stack exchange,提问作者Shankar Naik
相关产品推荐
相关产品推荐

