如何在自定义绘制的UIView中实现文字擦除效果?
实现文字擦除UIView的解决方案
嘿,我懂你想做的是用文字当“橡皮擦”,在UIView上擦除底色的效果对吧?你当前的思路方向是对的——用kCGBlendModeClear混合模式实现擦除,但大概率卡在了文字绘制的细节上,比如字体创建不完整导致文字没渲染出来,自然看不到擦除效果。
我给你整理了完整可运行的实现方案,分两种常用方式:
方式一:在drawRect中直接绘制(传统UIView绘制)
适合基础的静态擦除场景:
- (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); // 第一步:绘制要被擦除的底色(这里用白色举例) CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor); CGContextFillRect(ctx, self.bounds); // 关键操作:设置混合模式为Clear,后续绘制的内容会直接清除对应区域像素 CGContextSetBlendMode(ctx, kCGBlendModeClear); // 第二步:用UIKit方法设置文字属性,避开手动创建CGFont的坑 NSString *eraseText = @"我是橡皮擦"; UIFont *textFont = [UIFont boldSystemFontOfSize:50]; NSDictionary *textAttrs = @{ NSFontAttributeName: textFont, // 文字颜色不影响擦除效果,只是绘制时的占位色 NSForegroundColorAttributeName: [UIColor blackColor] }; // 绘制文字,此时文字区域会直接擦除之前的白色底色 [eraseText drawAtPoint:CGPointMake(20, 40) withAttributes:textAttrs]; }
方式二:用UIGraphicsImageRenderer绘制(iOS 10+推荐)
更灵活,适合需要复用绘制结果或动态更新的场景:
- (void)setupEraseView { UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:self.bounds.size]; UIImage *eraseImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext *rendererCtx) { CGContextRef ctx = rendererCtx.CGContext; // 绘制底色(这里用浅灰色举例) CGContextSetFillColorWithColor(ctx, [UIColor lightGrayColor].CGColor); CGContextFillRect(ctx, self.bounds); // 设置擦除混合模式 CGContextSetBlendMode(ctx, kCGBlendModeClear); // 绘制擦除文字 NSString *eraseText = @"文字擦除效果"; UIFont *textFont = [UIFont systemFontOfSize:45]; NSDictionary *textAttrs = @{NSFontAttributeName: textFont}; [eraseText drawInRect:CGRectMake(10, 30, self.bounds.size.width-20, 60) withAttributes:textAttrs]; }]; // 将绘制好的图片设置为view的内容 self.layer.contents = (__bridge id)eraseImage.CGImage; }
几个必须注意的细节:
- 一定要把你的UIView的
backgroundColor设为[UIColor clearColor],避免系统默认背景覆盖擦除效果 - 别手动创建CGFont(容易踩字体名称、编码的坑),用UIKit的
UIFont配合属性字典绘制文字更可靠 kCGBlendModeClear的核心作用是让后续绘制内容直接清除对应区域像素,只要文字能正确渲染,就能看到擦除效果
你之前的代码里CGFontCreateWithFontName(CFStringCreateWithCStr...这部分没写完,大概率是字体创建失败导致文字没渲染,所以看不到擦除效果,换成上面的UIKit文字绘制方法就能解决啦。
内容的提问来源于stack exchange,提问作者Liftoff
相关产品推荐
相关产品推荐

