You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Objective-C中绘制带数字的实心彩色圆形?求更优实现方案

嘿,这个需求我之前在项目里经常碰到,完全没必要用图片叠加的方式——直接用系统控件改造或者Core Graphics绘制都更简便,还能避免图片适配的麻烦!下面给你两种实用方案:

方案一:用UILabel/UIButton快速改造(最省心)

如果只是需要简单的实心彩色圆加数字,直接用系统的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:32:58