使用NSUndoManager获得乐趣和收益

在现实世界中,现实世界仅限于计算机软件领域,撤消操作是一种普遍现象。 在考虑撤消操作时,通常会想到的用例是生产力应用程序(例如文档编辑器)或创造力应用程序(例如照片编辑器)。 确实,在LIVEOP X iOS应用程序中,绘图组件也是我们与NSUndoManager的第一次接触。

在LIVEOP X中,生产力起着关键作用。在紧急情况下,没有错误,误解或“试图打开和关闭”的空间。 如果应用程序没有响应用户期望的响应,则用户将简单地放弃该应用程序,将平板电脑存放起来并提供急救,而无需提供应用程序必须提供的所有基本信息。 为避免这种情况并达到为用户创造价值的目标,我们必须在生产力和应用程序性能方面设定最高标准。 这始于开发,有时我们会发现自己从意外来源获得了一些帮助。

在我们的GEO工具中,第一响应者会得到一个油漆桶,以在地图上绘制说明并与他人共享。 手绘指令在地图上的所有缩放级别上实时呈现,就像它们从一开始就存在。 该工具特别有用,它可以为仍在飞行中的设备勾勒出进场路径,或评估潜在有毒气体云的影响区域。 绘图工具的一部分是撤消按钮,用于撤消先前绘制的线段。 下面给出一个例子。

在代码中看起来如何? 很简单的。 在将线段添加到地图的同时,我们使用单个NSUndoManager为完全相同的线段注册了撤消操作。

  -(void)addHandDrawnAnnotations:(NSArray  *)annotations { 
for(注释中的id注释){[self.mapController addAnnotation:annotation];} [self.undoManager registerUndoWithTarget:self选择器:@selector(removeHandDrawnAnnotations :) object:annotations];}

NSUndoManager的API使其非常易于使用。 实际上,它在代码库中的适用性和适用性远远超出了前面所述的典型用例。

在明确的用户环境之外撤消操作

在我们的GEO配置门户中,客户可以定义自定义动作并将其附加到地图图层。 然后,只要在iOS应用程序中选择了属于地图图层的注释,便会执行为该图层配置的动作。 动作可能是选择其他地图图层,或显示其他UI元素。 动作只是一个描述,告诉应用程序当用户选择注释时该怎么做。 当操作在服务器配置中发生更改时,我们只需重新创建代表该操作的视图模型即可。

这些动作仅运行一次。 但是,无论是通过编程方式还是由用户取消选择地图图层,或者从同一地图图层中选择新注释时,我们都希望使先前执行的动作的影响无效:所有动作均采用纯净状态。 最初认为,这将需要大量的代码来检查已执行了哪些操作,在应用程序中查找结果并将其与结果匹配,然后将其丢弃。 但是,将结果(例如,由于操作而添加的额外UI)与操作视图模型耦合在一起是不可行的,因为视图模型是动态创建的。 NSUndoManager在这里形成了一个很好的解决方案。 另外,总的来说,我们希望尽可能避免冗长的代码。

在地图层视图模型上,我们定义了一个带有一组的NSUndoManager 。 创建时会打开该组。 然后,每当我们要撤消图层的操作时,我们都会关闭该组,调用-undo ,然后打开一个新组。 我们使用分组以便一次摆脱所有动作。 撤消操作在执行操作的同时注册。 如果是向UI添加按钮的操作,则如下所示:

这里的model是地图图层视图模型。 请注意, NSUndoManager提供了两种注册撤消操作的方法。 如果撤消选择器只有一个参数,则可以使用registerUndoWithTarget:selector:object 。 对于更复杂的撤消处理,我们可以求助于registerUndoWithTarget:handler:

当取消选择该层或从同一层选择一个新的注释时,我们关闭一个撤消组并调用-undo ,导致所有操作的结果都将被丢弃:

总之, NSUndoManager是一种非常强大的工具,在很多人可能不会立即想到它的情况下派上用场。 在上面突出显示的用例中,我们为自己节省了很多不必要且难以维护的意大利面条代码。