Pausing UndoManager (with CoreData)

I have undoManager working with a CoreData backed app but I would like to either pause undoManager during certain data changes or be able to pop the last undo off the undoManager “stack".

Ideally, I would like to

  • Delete Object A
  • Pause undoManager
  • Delete Object B
  • Unpause undoManager
  • Delete Object C

So the undo stack looks like:

  • Undo Delete Object C
  • Undo Delete Object A

In this instance, object B was created by an unfinished multi-screen workflow that was canceled by the user - but there are a few other examples in my app as well.

So far I have tried disableUndoRegistration() like so:

container.viewContext.processPendingChanges()
container.viewContext.undoManager?.disableUndoRegistration()

This has no effect. The undo action is still recorded.

I have tried swapping the undoManager to nil after parking it elsewhere and then reassigning it after deleting object B. This effectively works the same as undoManager.removeAllActions().

And I have tried removing all actions for the target Object B after deleting Object B. Also with no effect.

viewContext.undoManager?.removeAllActions(withTarget: objectB)

My workaround is to simply reset the entire stack with .removeAllActions() but that’s not ideal.

Any ideas on how to make this work?

Thanks.

Answered by DTS Engineer in 797945022

Disabling and then endabling undo registration, as shown below, is supposed to work in the described use case:

    context.processPendingChanges()
    context.undoManager?.disableUndoRegistration()
    // Make changes that you don't want to record in the undo stack.
    context.processPendingChanges()
    context.undoManager?.enableUndoRegistration()

Since it seems that you have tried and confirmed that the code didn't work, do you have a minimal project that can demonstrate the issue? If yes, I'll be interested in taking a look.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

Disabling and then endabling undo registration, as shown below, is supposed to work in the described use case:

    context.processPendingChanges()
    context.undoManager?.disableUndoRegistration()
    // Make changes that you don't want to record in the undo stack.
    context.processPendingChanges()
    context.undoManager?.enableUndoRegistration()

Since it seems that you have tried and confirmed that the code didn't work, do you have a minimal project that can demonstrate the issue? If yes, I'll be interested in taking a look.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Well, after creating a minimal project to demonstrate the issue using the IOS App template from Xcode, I found that the following code does indeed work as expected:

context.processPendingChanges()
context.undoManager?.disableUndoRegistration()
 // Make changes that you don't want to record in the undo stack.
context.processPendingChanges()
context.undoManager?.enableUndoRegistration()

I will work to figure out where my error is in my app.

Thanks for your response.

Pausing UndoManager (with CoreData)
 
 
Q