0

Ok, So i want to add the ability to undo certain actions in my app. I was going to create a way to do it, with my own protocals or something, but then I found out about NSUndoManager. I would like to use the built in foundation way, but I can't seem to figure it out. I need to undo multiple dice rolling, so if I could store the previous rolls, as objects in an NSArray, would probably be the best. I could use an NSMutableString, but the array would be preferred.

Then I know you can shake to undo, but I would rather have a button. These has been giving me the most trouble. I've included my attempts below. None of those have worked. Any help would be appreciated.

In viewDidLoad:

undoManager = [[NSUndoManager alloc] init];

Then in the method that rolls the dice, I tried:

   [[undoManager prepareWithInvocationTarget:self] undoButton];
    [[undoManager prepareWithInvocationTarget:self] 
    [[undoManager prepareWithInvocationTarget:self] setString:[NSString stringWithFormat:@"%i", dice1num]];

setStrings:[NSArray arrayWithObjects:[NSString stringWithFormat:@"%i", dice1num]
    [NSString stringWithFormat:@"%i", dice1num],
    [NSString stringWithFormat:@"%i", dice1num],
    [NSString stringWithFormat:@"%i", dice1num],
    [NSString stringWithFormat:@"%i", dice1num], nil]];
[[undoManager prepareWithInvocationTarget:@selector()];
[undoManager setActionName:@"A roll"];

And then here is the IBAction that links to the undo button:

-(IBAction)undoButton{
           [undoManager undo];
}

Thanks in advance

Andrew
  • 3,874
  • 5
  • 39
  • 67
  • 1
    My answer to this question might also be helpful here: [How does undo/redo basically work on iPhone OS?](http://stackoverflow.com/questions/2449268/how-does-undo-redo-basically-work-on-iphone-os) – Brad Larson Apr 04 '11 at 00:27
  • Brad, I skimmed your answer and it looks really good. I wish I had seem that a few days ago. I'll probably take a few things away from that. Thanks for your help – Andrew Apr 04 '11 at 02:46
  • Apple's DotViewUndo sample code helped me get up and running. It's a tiny little project gathering dust here: https://developer.apple.com/library/mac/samplecode/DotViewUndo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008851-Intro-DontLinkElementID_2 – original_username Apr 09 '14 at 17:48

1 Answers1

5

I think you have gotten the function of the NSUndoManager wrong. An undo manager is like a stack of invocations which are needed to reverse the thing you just did. So in principle your idea is right to use a collection object in your case an NSArray to store multiple undo steps. Unfortunately it works a litte bit different.

How NSUndoManager works

An undo manager works by maintaining a stack of undo steps in memory. For each step in your case dice roll you want to undo you register an invocation object using the - (void)registerUndoWithTarget:self selector:@selector(setMyObjectTitle:) object:currentTitle method. You do this for every dice roll. Do only register one operation at a time.

For undoing you call the undo method as you did and what happens then is that the undo manager pops an operation of the undo stack and executes it.

Your main mistake was to try to reinvent how the undo manager works. Do not register an array, just use one dice roll at a time.

Apple's undo architecture manual

GorillaPatch
  • 5,007
  • 1
  • 39
  • 56
  • Thank you very much. I had to do a little playing around and modify the concept to fit my needs but I got it. Thanks again – Andrew Apr 03 '11 at 23:09