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

iOS绘图应用撤销功能实现:touchesEnded后移除数组末尾图片

实现iOS绘图应用的撤销功能

嘿,你思路完全正确!要实现撤销按钮功能,核心就是每次完成绘制后把当前的画布状态存入images数组,然后在撤销操作时移除数组最后一项并恢复对应的状态。咱们一步步来调整代码:

1. 每次绘制完成后保存状态

在touchesEnded方法里,当你把临时图层合并到主图层后,把当前主图层的图片存入images数组。记得要判断图片不为空,避免存入无效的nil值:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if !swiped {
        // 绘制单点
        drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint)
    }

    // 合并临时图层到主图层
    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

    // 保存当前画布状态到数组
    if let currentCanvasImage = mainImageView.image {
        images.append(currentCanvasImage)
    }

    print("touch ended")
}

2. 实现撤销按钮的点击事件

创建撤销按钮的IBAction方法,在这里处理数组的弹出和状态恢复。同时要处理边界情况:比如数组为空或者只有初始状态时,要清空画布并禁用撤销按钮:

@IBAction func undoButtonTapped(_ sender: UIButton) {
    // 至少需要有两次状态记录才能撤销(初始状态+至少一次绘制)
    guard images.count > 1 else {
        // 回到初始空白状态
        mainImageView.image = nil
        images.removeAll()
        // 更新撤销按钮状态
        undoBtn.isEnabled = false
        undoBtn.setImage(UIImage(named: "undo_icon"), for: .normal)
        return
    }

    // 移除最后一次绘制的状态
    images.removeLast()
    // 恢复到上一个画布状态
    mainImageView.image = images.last
    // 清空临时图层,避免残留绘制痕迹
    tempImageView.image = nil

    // 如果只剩初始状态,禁用撤销按钮
    if images.count <= 1 {
        undoBtn.isEnabled = false
        undoBtn.setImage(UIImage(named: "undo_icon"), for: .normal)
    }
}

3. 初始化状态处理

别忘了在viewDidLoad里初始化images数组,把初始的空白状态(或者你的默认背景图)存进去,这样第一次撤销能正确回到初始状态:

override func viewDidLoad() {
    super.viewDidLoad()
    // 存入初始状态(空白画布或默认背景)
    images.append(mainImageView.image ?? UIImage())
    // 初始时没有绘制内容,禁用撤销按钮
    undoBtn.isEnabled = false
}

这样调整后,你的撤销按钮就能完美工作啦——每次点击都会移除用户最后绘制的线条,恢复到上一步的画布状态。

内容的提问来源于stack exchange,提问作者Tessa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:24:43