Help with NSUndoManager
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 wa开发者_如何学运维y, 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
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
精彩评论