iPhone 操作系统上的撤消/重做基本上是如何工作的?

发布于 2024-08-25 04:55:36 字数 150 浏览 4 评论 0原文

我的应用程序尚未使用核心数据。我是否必须使用 Core Data 进行撤消/重做?

并且:用户如何进行撤消/重做?我从未见过它的实际应用,也从未使用过它。如果我愿意的话,不知道该怎么做。任何地方都没有撤消/重做按钮。但他们说它具有撤消/重做功能。那么用户如何触发这个呢?

My app doesn't use Core Data yet. Is it true that I must use Core Data for undo/redo?

And: How does the user do the undo/redo? I've never seen it in action, and never ever used it. Don't know how I should do it if I wanted to. There's no undo/redo button anywhere. Yet they say it has undo/redo. So how does the user trigger this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

东走西顾 2024-09-01 04:55:36

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

- (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"];
}

可用于观察属性的更改,创建将撤消对这些属性的编辑的反向 NSInvoking。

撤消不需要核心数据,但它使撤消变得非常非常容易。每次您编辑数据模型时,它都会为您处理这些撤消操作的创建,包括复杂的操作,例如沿着托管对象的层次结构进行级联删除。

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

视图控制器出现在屏幕上时需要成为第一响应者。这可以通过在 -loadView-viewDidLoad 中调用 [selfBecomeFirstResponder] 来完成,但我发现视图控制器在之后立即出现在屏幕上launch 需要将此消息延迟一点才能正常工作:

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

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

iPhone OS 3.0 brought over the concept of NSUndoManager from the Mac, which is what enables undo on the iPhone. NSUndoManager maintains a stack of NSInvocations which are the opposite actions to any edits or other changes you make. For example,

- (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"];
}

can be used to observe changes in properties, creating inverse NSInvocations that will undo edits to those properties.

Core Data is not needed for undo, but it makes it much, much easier. It handles the creation of these undo actions for you every time you edit your data model, including complex actions like a cascading delete down a hierarchy of managed objects.

On the iPhone, to enable undo / redo, you need to set up a few things. First, NSManagedObjectContexts on the iPhone don't have an undo manager by default, so you need to create one:

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

This code would typically go right after where you would have created your NSManagedObjectContext.

Once an undo manager is provided for your context, you need to enable the default gesture for undo on the iPhone, a shake of the device. To let your application handle this gesture automatically, place the following code within the -applicationDidFinishLaunching: method in your application delegate:

application.applicationSupportsShakeToEdit = YES;

Finally, you will need to set up each view controller that will be capable of handling the shake gesture for undo. These view controllers will need to report back the undo manager to use for that controller by overriding the -undoManager method:

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

The view controllers will also need to be able to become the first responder to handle gestures, so the following method is needed:

- (BOOL)canBecomeFirstResponder 
{
    return YES;
}

The view controller will need to become the first responder when it appears onscreen. This can be done by calling [self becomeFirstResponder] in -loadView or -viewDidLoad, but I have found that view controllers which appear onscreen immediately after launch need to have this message delayed a bit in order for it to work:

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

With all this in place, you should get automatic undo and redo support courtesy of Core Data, with a nice animated menu.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文