iOS: 为画板App增加 Undo/Redo(撤销/重做)操作

这个随笔的内容以上一个随笔为基础,(在iOS中实现一个简单的画板),上一个随笔实现了一个简单的画板:

今天我们要为这个画板增加Undo/Redo操作,当画错了一笔,可以撤销它,或者撤销之后后悔了,还可以还原。而且我们要通过晃动手机来触发Undo/Redo的选择。

这个demo使用NSUndoManager实现Undo/Redo操作,NSUndoManager 的实现原理是它作为一个记录器,每次数据变化,我们要用这个记录器记录一个相反的操作,当需要undo的时候,它通过执行这个相反的操作就可以实现了。对于这个画板demo,我们通过把array中的Line首尾连接起来实现的,所以要想还原到上次的状态,我们通过从array中remove最后添加的那条线就可以实现了。

NSUndoManager需要两个步骤:

第一步,注册NSUndoManger操作,既上边提到的注册一个相反的操作。(先只实现undo操作)

首先添加一个相反的操作,即一个从array中remove Line的方法,方法名就叫removeLine:

然后修改addLine方法,注册刚刚添加的removeLine方法:

但是这里有一个问题:因为当手指在屏幕移动的时候,touchMove方法会被持续多次触发,所以画一笔,是由多个Line组成的。所以addLine会调用多次,如果我们直接undo,只是remove掉了一条Line,但是画一笔是由多个Line组成,这样只能移掉一笔中的一部分,即结尾的那部分。

那要怎么办呢?如何一次移除多个Line,即画一笔所包含的一组Line。

NSUndoManager有一个分组的概念,就是为了解决这类问题的。

正常情况下,画一笔肯定会触发3个方法,依次是touchBegan, touchMove 和 touchEnd,所以我们可以通过touchBegan和touchEnd就能分辨出画一笔的开始和结束。既:

这样我们再执行撤销的时候就是一次remove一组的Line了。

第二步,执行Undo

在UI添加一个按钮,作为Undo按钮,按钮的点击事件中简单地调用undo方法就可以了。既:

Undo操作这样就算是完成了。

Redo操作和Undo操作道理一样,我们只需要修改下removeLine方法,当remove一条Line的时候,也注册一个相反的操作,即注册addLine方法,修改后的removeLine方法:

晃动触发Undo/Redo操作

其实我们根本不需要在UI添加Undo/Redo按钮,直接晃动手机就会自动弹出Undo/Redo选项,而且晃动的功能是自动打开的。

如果需要关闭它,需要设置:

在这个demo中,请不要将此属性设置为NO。

最后看下效果:(在模拟器中无法晃动,使用快捷键进行了模拟)

相关源代码:github

时间: 2024-10-08 22:45:56

iOS: 为画板App增加 Undo/Redo(撤销/重做)操作的相关文章

iOS绘图例2:增加Undo/Redo功能

在工程中添加Undo.Redo的按钮图片,每个按钮都有可用和不可用两种状态图片,共4个图片. 在StoryBoard中添加两个按钮,设置图片属性和自动布局约束. 按住 Ctrl 拖动按钮到 ViewController.mm 中,创建属性变量和动作方法. @interface ViewController () @property (weak, nonatomic) IBOutlet UIButton *undoButton; @property (weak, nonatomic) IBOutl

C#中泛型容器Stack<T>的用法,以及借此实现”撤销/重做”功能

.Net为我们提供了众多的泛型集合.比如,Stack<T>先进后出,Queue<T>先进先出,List<T>集合元素可排序,支持索引,LinkedList<T>,双向链表的泛型实现,不支持索引;ISet<T>不允许被复制,他有2个实现,一个是HashSet<T>,不维持集合元素的排序,另一个是SortedSet<T>,支持集合元素的排序;IDictionary<TKey, TValue>是一个字典集合的泛型接口

在iOS中实现一个简单的画板App

在这个随笔中,我们要为iPhone实现一个简单的画板App,类似于手写输入中写字的面板.但是我们的画板支持画笔颜色的选择. 首先需要指出的是,这个demo中使用QuarzCore进行绘画,而不是OpenGL.这两个都可以实现类似的功能,区别是OpenGL更快,但是QuarzCore更简单. 第一步,新建Xcode项目,项目名称就叫SimplePaint. 第二步,添加QuarzCore.framework到项目中. 第三步,创建一个新类,类名叫Line.它代表在iPhone的屏幕上绘画时候的线.

undo/redo功能的原理和思路

一些具有操作记录的系统,如店铺装修.富文本编辑等,都具有undo/redo功能,可实现界面操作过程的撤销和恢复,简述开发undo/redo功能的原理和思路. undo是将用户上一步做的操作对程序造成的改动恢复到改动之前,而redo操作是指重新实现这种改动. undo/redo操作的实现方式分为两类:记录数据和记录操作. 记录数据是指将信息编辑窗口打开时,保存原始数据,然后记录用户每次操作后的结果数据,这里的数据是指信息编辑窗口中所有可能发生变动的数据.做undo操作时程序将用户上一步操作前的数据

IOS开始对App Store大扫除:你的APP更新了吗?

成都亿合科技小编从北京商报了解到,对于开发APP应用的要注意啦,IOS要开始对App Store大扫除:你的APP更新了吗? 日前苹果App Store的开发者们发送邮件,表示将实施一个持续评估应用行动,删除那些不再按照预期运行.不遵守目前审核指南或陈旧的应用. 据了解,苹果此举主要是为了保证App Store商店当中内容的高质量,苹果iOS系统和Android系统相差最大的就是体验和应用质量,如果应用逐渐沦陷降低品质,那么苹果iOS的优势将会失去.而应用商店当中有很多“僵尸”应用甚至有人利用苹

Oracle Undo Redo(转)

转贴: http://www.cuug.com/xueyuanzhuanqu/jishuwenzhang/201108/jishuwenzhang-245.html http://paul0407.blogspot.tw/2008/01/oracle-redoundorollback-segment.html http://blog.csdn.net/robinson_0612/article/details/5731158 Oracle Undo Redo Redo redo 记录 trans

ios俩个APP之间跳转、传值

两个APP之间的跳转是通过[[UIApplication sharedApplication] openURL:url]这种方式来实现的. 1.首先设置第一个APP的url地址 2.接着设置第二个APP的url地址 3.需要跳转的时候 NSString *urlString = [NSString stringWithFormat:@"AppJumpSecond://%@",textField.text]; [[UIApplication sharedApplication] open

【转载】MySQL 日志 undo | redo

本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atomicity)  事务中的所有操作,要么全部完成,要么不做任何操作,不能只做部分操作.如果在执行的过程中发生  了错误,要回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过. - 原理  Undo Log的原理很简单,为了满

IOS研究之App转让流程须知详细介绍

 网络上有很多开发者提问怎么转让App并想知道具体的流程.实际上Appstore的App转让流程还是比较简单的,下面特酷吧根据自己的实际操作总结下iOS Appstore中App的转让流程,供大家参考.对网络开发不明白的朋友可以看IOS研究之网络编程Cocoa Streams使用详解 一,App的转让 (1)App转让的条件 至少有在Appstore上发售的版本,即应用状态为:"ready for sale".其他一些条件参考itunes connect中应用详情页面点击"