Vin*_*ini 5 xcode objective-c nsundomanager ios
我想在绘图应用程序中对图形上下文执行撤消操作.按下撤消时,我想移动到包含旧图形的上一个上下文.
例如:
我在上下文中有一个矩形.在拖动时,我将矩形移动到新位置并重绘它.现在,当我按下撤消按钮时,我想将矩形移动到上一个位置.我怎样才能做到这一点?
我只是基本的想法NSUndoManager
.
请帮忙!
谢谢.
您推断的功能并不存在.换句话说"图形上下文不能以这种方式工作(免费)." 你可能已经看到了函数UIGraphicsPushContext
和UIGraphicsPopContext
,但他们不这样做,你是在谈论这里.它们所代表的"推"和"弹出"操作对图形上下文的尚未渲染的方面进行操作:例如当前的填充和描边颜色,剪辑矩形和变换矩阵.一旦某些东西被渲染到上下文中 - 即路径/ rect /等.已被描边或填充,或图像已被合成到上下文中 - 它将永久呈现."回归"的唯一方法是以某种方式重新创建以前的状态.不幸的是,没有任何神奇的内置UIGraphicsContext
可以让你发生这种情况.
有几种方法可以解决这个问题.正如另一位用户所提到的,您可以在每次用户操作后捕获上下文的状态.简而言之,这意味着您的文档"模型"是位图堆栈.这将非常快速地获得内存密集 - 位图占用大量内存.你可以对这种方法进行优化以获得更多的利润,例如只保存每帧之间已经改变的区域,压缩位图,将它们交换到磁盘等等.有真正可用的应用程序.使用这种方法工作的App Store,但该方法本质上是有限的,并且您最终将花费大量精力来优化和管理已保存的撤消状态堆栈.
当然,还有其他值得考虑的方法.最简单的方法是让您的实际文档模型是一堆小的(即非位图)数据结构,描述重新创建上下文状态所需的操作.当用户撤消时,您只需删除堆栈顶部的操作,并通过回放剩余堆栈来重新创建图形上下文.对于"添加"类型的应用程序(想想"刷子")来说,这是一个不错的方法,但即使在您描述的在画布上移动形状的简单场景中也会开始下降.它最终也会遇到一些与位图堆栈方法相同的问题 - 您拥有的操作越多,重新创建状态所需的时间就越长,因此您不可避免地会定期制作位图快照等.
对于您所描述的画布上对象场景("移动形状"操作),还有多种方法.一种经典的方法是让您的文档模型成为一组更小,更具体的数据结构,用于描述画布的当前状态.想想一个Shape
类等等.在最简单的情况下,当用户向画布添加一个矩形时,会将一个Shape
实例添加到一个z排序的形状数组中.只要形状列表发生变化,就可以通过按Z顺序绘制每个形状来重新生成上下文.要实现撤消功能,每次改变形状数组时,还要使用NSUndoManager
记录调用,当重放时,将导致反向操作发生.
如果你的形状添加操作如下所示:
[shapeArray insertObject: newShape atIndex: 5];
Run Code Online (Sandbox Code Playgroud)
那么你会同时用以下方法做到这一点NSUndoManager
:
[[undoManager prepareInvocationWithTarget: shapeArray] removeObjectAtIndex: 5];
Run Code Online (Sandbox Code Playgroud)
当用户单击undo时,NSUndoManager
播放该调用,并shapeArray
返回其先前状态.这是经典NSUndoManager
模式.它运作良好,但也有一些缺点.例如,跨应用程序终止持久化撤销堆栈并不一定是直截了当的.由于应用程序终止在iOS上很常见,并且用户通常希望应用程序能够跨终端无缝地恢复状态,因此根据您的要求,撤销堆栈无法在应用程序终止后继续存在的方法可能不具备启动性.还有其他更复杂的方法,但它们大多只是其中一个主题的变体.一个经典值得一读的就是命令模式从四书,设计模式的岗.
无论您选择何种方法,这种应用都将是一个挑战.这个图形撤消功能根本不是UIGraphicsContext
"免费" 内置的东西.您已在评论中多次询问过一个示例.我很遗憾地说,但这是一个足够复杂的概念,在StackOverflow答案的限制范围内提供一个工作示例是不可能的.希望这些想法和指针是有帮助的.当然也有许多开源绘图应用程序可供您查看灵感(虽然我个人并不了解iOS的任何开源绘图应用程序.)
归档时间: |
|
查看次数: |
1947 次 |
最近记录: |