如何清空UIView?iOS绘图应用画布清空实现方案
实现绘图视图的一键清空功能
嘿,我看了你的绘图代码和需求,这里帮你调整一下,确保清空按钮能正常工作,同时修正几个小问题让代码更规范易读:
先说说现有代码里的小问题
- 拼写错误:比如
storkes应该是strokes,类名subClassOFUIVIEW不符合Swift的驼峰命名规范 - IBOutlet绑定错误:
@IBOutlet weak var jj: draw!里的draw应该是你的绘图视图类drawViewSwift(我后面统一改成更规范的DrawViewSwift) clear()方法的实现有点绕,其实可以更直接,不需要额外的clearing标记
修正后的完整实现
1. 基础视图类(修正命名)
import UIKit // 用驼峰式命名更符合Swift规范 class DrawViewBase: UIView { override func awakeFromNib() { super.awakeFromNib() layer.shadowOpacity = 1 layer.shadowOffset = CGSize(width: 1, height: 1) layer.shadowPath = CGPath(rect: bounds, transform: nil) } }
2. 核心绘图视图类
import UIKit // 结构体名同样用大驼峰 struct Stroke { let startPoint: CGPoint let endPoint: CGPoint let color: CGColor } class DrawViewSwift: DrawViewBase { var isDrawing = false var lastPoint: CGPoint? // 改成可选值,避免强制解包崩溃 var strokeColor: CGColor = UIColor.black.cgColor var strokes = [Stroke]() // 修正拼写错误 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard !isDrawing else { return } isDrawing = true guard let touch = touches.first else { return } lastPoint = touch.location(in: self) } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { guard isDrawing, let touch = touches.first, let lastPoint = lastPoint else { return } let currentPoint = touch.location(in: self) let newStroke = Stroke(startPoint: lastPoint, endPoint: currentPoint, color: strokeColor) strokes.append(newStroke) self.lastPoint = currentPoint setNeedsDisplay() // 每次移动都触发重绘,实时显示路径 } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { guard isDrawing, let touch = touches.first, let lastPoint = lastPoint else { return } isDrawing = false let currentPoint = touch.location(in: self) let newStroke = Stroke(startPoint: lastPoint, endPoint: currentPoint, color: strokeColor) strokes.append(newStroke) self.lastPoint = nil setNeedsDisplay() } // 这就是清空画布的核心方法 func clearCanvas() { strokes.removeAll() // 清空所有绘制路径 setNeedsDisplay() // 触发重绘,画布就变成空白了 } override func draw(_ rect: CGRect) { super.draw(rect) guard let context = UIGraphicsGetCurrentContext() else { return } context.setLineWidth(10) context.setLineCap(.round) // 遍历所有路径绘制 for stroke in strokes { context.beginPath() context.move(to: stroke.startPoint) context.addLine(to: stroke.endPoint) context.setStrokeColor(stroke.color) context.strokePath() } } }
3. 视图控制器的两种实现方式
方式一:用Storyboard绑定视图和按钮
如果你是用Storyboard搭建界面,这样写:
import UIKit class ViewController: UIViewController { // 在Storyboard里把你的绘图视图绑定到这个IBOutlet @IBOutlet weak var drawView: DrawViewSwift! // 清空按钮的点击事件(Storyboard里绑定这个方法) @IBAction func clearButtonTapped(_ sender: UIButton) { drawView.clearCanvas() } }
方式二:纯代码创建视图(和你原来的MyViewController对应)
import UIKit class MyViewController: UIViewController { override func loadView() { let drawView = DrawViewSwift() drawView.backgroundColor = .white // 创建清空按钮,调整位置让它更合理 let clearButton = UIButton(type: .system) clearButton.setTitle("清空画布", for: .normal) clearButton.frame = CGRect(x: 50, y: UIScreen.main.bounds.height - 120, width: UIScreen.main.bounds.width - 100, height: 44) clearButton.addTarget(self, action: #selector(handleClearTap), for: .touchUpInside) drawView.addSubview(clearButton) self.view = drawView } @objc private func handleClearTap() { (view as? DrawViewSwift)?.clearCanvas() } }
关键逻辑解释
- 清空原理:我们所有的绘制路径都存在
strokes数组里,draw(_:)方法会根据这个数组的内容来绘制图形。所以只要清空数组再调用setNeedsDisplay(),视图重绘时就没有路径可以画,自然就变成空白画布了。 - 可选值优化:把
lastPoint改成可选值,避免了强制解包可能导致的崩溃,代码更安全。 - 命名规范:Swift里类、结构体用大驼峰,变量用小驼峰,这样团队协作或者自己后期维护时更容易读懂代码。
内容的提问来源于stack exchange,提问作者user8105388
相关产品推荐
相关产品推荐

