使用Core Graphics绘制线条时如何清除Canvas背景色?
解决Canvas擦除背景显示底层图片的问题
你的问题源于几个关键设置错误,导致无法实现擦除效果,以下是具体修正方案:
核心问题分析
- Canvas背景色设置错误:你给Canvas设置了白色背景,即使绘制透明线条,白色背景依然会遮挡底层图片。
super.draw(rect)干扰:调用父类的draw方法会先绘制Canvas的背景色,覆盖后续的擦除操作。- 坐标获取错误:
touchesMoved中用location(in:nil)获取的是相对于窗口的坐标,而非Canvas自身的坐标,导致线条位置偏移。 - 擦除方式错误:仅设置
strokeColor为透明无法实现擦除,需要利用图形上下文的混合模式。
修正后的代码
Canvas类修改
import UIKit class Canvas: UIView { var lines = [[CGPoint]]() override func draw(_ rect: CGRect) { // 去掉super.draw(rect),避免绘制默认背景 guard let context = UIGraphicsGetCurrentContext() else { return } context.setLineWidth(20) context.setLineCap(.butt) // 设置混合模式为擦除,绘制内容会变成透明 context.setBlendMode(.clear) lines.forEach { line in guard let firstPoint = line.first else { return } context.move(to: firstPoint) // 简化线条绘制逻辑 for point in line.dropFirst() { context.addLine(to: point) } } context.strokePath() } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { lines.append([CGPoint]()) } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { guard let point = touches.first?.location(in: self) else { return } // 修正坐标获取对象 guard var lastLine = lines.popLast() else { return } lastLine.append(point) lines.append(lastLine) setNeedsDisplay() } }
ViewController修改
class ViewController: UIViewController { let canvas = Canvas() override func viewDidLoad() { super.viewDidLoad() // 先添加底层图片视图(替换成你的图片名称) let backgroundImageView = UIImageView(image: UIImage(named: "your_background_image")) backgroundImageView.frame = view.frame backgroundImageView.contentMode = .scaleAspectFill view.addSubview(backgroundImageView) // 添加Canvas,背景设为透明 view.addSubview(canvas) canvas.backgroundColor = .clear canvas.frame = view.frame } }
关键修改点说明
- 移除
super.draw(rect):阻止UIView默认绘制背景色的行为,避免干扰擦除效果。 - 设置混合模式为
.clear:让绘制的线条区域变成透明,直接显示底层图片。 - Canvas背景设为
.clear:确保Canvas本身不会遮挡底层内容。 - 修正坐标获取:用
location(in: self)获取相对于Canvas的坐标,保证线条位置准确。
内容的提问来源于stack exchange,提问作者NinjaDeveloper
相关产品推荐
相关产品推荐

