iPhone OS上的撤销/重做基本是如何工作的?

12

我的应用程序尚未使用Core Data。 是否确实需要使用Core Data来实现撤销/重做?

另外:用户如何执行撤销/重做操作? 我从未见过它实际运行,也从未使用过它。 如果我想使用它,我该怎么做? 任何地方都没有撤销/重做按钮。 然而他们说它有撤销/重做功能。 那么用户如何触发此操作?

1个回答

35

iPhone OS 3.0从Mac移植了NSUndoManager的概念,这使得iPhone上的撤销成为可能。NSUndoManager维护了一个NSInvocation栈,其中包含任何编辑或其他更改的相反操作。例如:

- (void)observeValueForKeyPath:(NSString*)keyPath
                      ofObject:(id)object
                        change:(NSDictionary*)change
                       context:(void*)context
{
    NSUndoManager *undo = [self undoManager];
    // Grab the old value of the key
    id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
    // Add edit item to the undo stack
    [[undo prepareWithInvocationTarget:self] changeKeyPath:keyPath 
                                                  ofObject:object 
                                                   toValue:oldValue];
    // Set the undo action name in the menu
    [undo setActionName:@"Edit"];
}

可以用于观察属性的更改,创建反向NSInvocations以撤销对这些属性的编辑。

Core Data不是必需的撤销,但它使得撤销变得更加容易。每次编辑数据模型时,它会为您处理创建这些撤销操作,包括级联删除一组管理对象的复杂操作。

在iPhone上启用撤销/重做需要设置一些东西。首先,iPhone上的NSManagedObjectContext默认没有撤销管理器,因此您需要创建一个:

NSUndoManager *contextUndoManager = [[NSUndoManager alloc] init];
[contextUndoManager setLevelsOfUndo:10];
[managedObjectContext setUndoManager:contextUndoManager];
[contextUndoManager release];       

这段代码通常会放在您创建NSManagedObjectContext之后的位置。

一旦为您的上下文提供了撤销管理器,您需要在iPhone上启用撤销的默认手势,即晃动设备。要让您的应用程序自动处理此手势,请将以下代码放置在应用程序委托的-applicationDidFinishLaunching:方法中:

application.applicationSupportsShakeToEdit = YES;

最后,您需要设置每个可以处理撤销摇晃手势的视图控制器。这些视图控制器需要通过覆盖-undoManager方法来报告要为该控制器使用的撤销管理器:

- (NSUndoManager *)undoManager;
{
    return [[[MyDatabaseController sharedDatabaseController] scratchpadContext] undoManager];
}

视图控制器还需要能够成为第一响应者来处理手势,因此需要以下方法:

- (BOOL)canBecomeFirstResponder 
{
    return YES;
}

当视图控制器出现在屏幕上时,它需要成为第一响应者。可以通过在- loadView-viewDidLoad中调用[self becomeFirstResponder]来完成此操作,但我发现视图控制器在启动后立即出现在屏幕上时,需要稍微延迟一下才能使其正常工作:

[self performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.3];

有了这一切,你应该得到由Core Data提供的自动撤销和重做支持,带有一个漂亮的动画菜单。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接