Swift绘图应用开发:实现图片数组存储与撤销按钮功能
实现绘图应用的撤销功能
嗨,我来帮你搞定这个撤销按钮的实现!你的代码已经完成了绘图的核心逻辑,现在只需要添加历史状态保存和撤销恢复的逻辑就可以了,步骤很清晰:
1. 添加历史记录数组
首先在你的ViewController类里,添加一个用来保存绘图历史状态的数组,每完成一笔绘制,我们就把当前的绘图状态存进去:
// 保存每一步绘图完成后的状态,用于撤销操作 private var drawingHistory: [UIImage] = []
2. 保存绘图状态到历史记录
修改你的touchesEnded方法,在把临时图层(tempImageView)合并到主图层(mainImageView)之前,先把当前主图层的状态存入历史数组——这样每完成一笔,我们就有了撤销的依据:
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { if !swiped { // draw a single point drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint) } // ✅ 新增:合并前保存当前主图层的状态到历史记录 if let currentMainImage = mainImageView.image { drawingHistory.append(currentMainImage) } // Merge tempImageView into mainImageView UIGraphicsBeginImageContext(mainImageView.frame.size) mainImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height),blendMode: CGBlendMode.normal, alpha: 1.0) tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: CGBlendMode.normal, alpha: opacity) mainImageView.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() tempImageView.image = nil floaty.isHidden = false postBtn.isHidden = false resetBtn.isHidden = false undoBtn.isHidden = false dismissBtn.isHidden = false }
3. 实现撤销按钮的点击逻辑
给你的撤销按钮(undoBtn)添加点击事件方法,逻辑很简单:检查历史数组是否有内容,如果有,就取出最后一个状态恢复到主图层,同时从数组里移除这个状态(因为已经撤销了):
@IBAction func undoButtonTapped(_ sender: UIButton) { // 没有历史记录就直接返回,避免崩溃 guard !drawingHistory.isEmpty else { // 这里可以加个提示,比如"没有可撤销的操作" return } // 取出最后一次的绘图状态并恢复 let lastDrawingState = drawingHistory.removeLast() mainImageView.image = lastDrawingState // 清空临时图层,避免残留的绘制痕迹 tempImageView.image = nil }
4. 重置功能的配套修改
别忘了给你的重置按钮(resetBtn)也加个逻辑,清空历史数组,不然重置后历史记录还在会导致奇怪的问题:
@IBAction func resetButtonTapped(_ sender: UIButton) { mainImageView.image = nil tempImageView.image = nil // ✅ 清空历史记录 drawingHistory.removeAll() // 其他你原本的重置逻辑... }
注意事项
- 这个方案是基于**每完成一笔(touchesEnded)**保存一次状态,如果你需要更精细的撤销(比如每移动一次手指就保存),可以调整保存时机,但这样会增加内存占用,一般一笔一存足够用了。
- 如果你的绘图应用会处理超大尺寸的图片,历史数组可能会占用较多内存,这时候可以考虑用磁盘缓存代替内存数组,但对于普通的绘图场景,内存数组完全够用。
内容的提问来源于stack exchange,提问作者Tessa
相关产品推荐
相关产品推荐

