12

我的应用还没有使用 Core Data。我必须使用核心数据进行撤消/重做是真的吗?

并且:用户如何进行撤消/重做?我从未见过它在行动中,也从未使用过它。如果我愿意,我不知道该怎么做。任何地方都没有撤消/重做按钮。然而他们说它有撤消/重做。那么用户如何触发呢?

4

1 回答 1

35

iPhone OS 3.0 从 Mac 中引入了 NSUndoManager 的概念,这就是在 iPhone 上启用撤消的原因。NSUndoManager 维护一个 NSInvocations 堆栈,它们是与您所做的任何编辑或其他更改相反的操作。例如,

- (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 上的 NSManagedObjectContexts 默认没有撤消管理器,所以你需要创建一个:

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;
}

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

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

完成所有这些后,您应该获得由 Core Data 提供的自动撤消和重做支持,以及漂亮的动画菜单。

于 2010-03-15T20:11:11.863 回答