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

使用Core Graphics绘制线条时如何清除Canvas背景色?

解决Canvas擦除背景显示底层图片的问题

你的问题源于几个关键设置错误,导致无法实现擦除效果,以下是具体修正方案:

核心问题分析

  1. Canvas背景色设置错误:你给Canvas设置了白色背景,即使绘制透明线条,白色背景依然会遮挡底层图片。
  2. super.draw(rect)干扰:调用父类的draw方法会先绘制Canvas的背景色,覆盖后续的擦除操作。
  3. 坐标获取错误:touchesMoved中用location(in:nil)获取的是相对于窗口的坐标,而非Canvas自身的坐标,导致线条位置偏移。
  4. 擦除方式错误:仅设置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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 11:35:51