so i have an NSImageView that can be dragged anywhere on the screen. every time it is finished repositioning (on touchesEnded) it's coordinates are saved to the userdefaults. i've added an observer to the userdefaults for this coordinates key, which allows for a simple implementation of NSUndoManager (undo move / redo move). all works well.
now for the exciting part!
the NSImageView can be locked into place, unable to move. if the view has moved, is then locked, any attempt to undo/redo the position of the view will present an alert telling the user the NSImageView is locked, and giving them the option to "Cancel" or "Unlock". tapping "Unlock" should either undo or redo the location of the image view, but instead the alert panel continues to pop up, over and over, until the last bit of hair on my head has been all pulled out.
now for the exciting part!
Code:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:OriginPositionFromCenterKey])
{
[COLOR="Green"]//Setup Undo Move[/COLOR]
redoMoveFloat = [[change objectForKey:NSKeyValueChangeNewKey] floatValue];
undoMoveFloat = [[change objectForKey:NSKeyValueChangeOldKey] floatValue];
[[undoManager prepareWithInvocationTarget:self] undoOrRedoMove:@"undo" toPosition:undoMoveFloat withOpposingMoveValue:redoMoveFloat];
[undoManager setActionName:[NSString stringWithFormat:NSLocalizedString(MoveButtonLabel, nil)]];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView == undoRedoMoveAlert)
{
if (buttonIndex == 1)
{
[self toggleLock];
if ([undoManager isUndoing])
[self undoOrRedoMove:nil toPosition:undoMoveFloat withOpposingMoveValue:redoMoveFloat];
if ([undoManager isRedoing])
[self undoOrRedoMove:nil toPosition:redoMoveFloat withOpposingMoveValue:undoMoveFloat];
}
}
}
- (void)undoOrRedoMove:(NSString *)toggle toPosition:(float)floatPositionFromCenter withOpposingMoveValue:(float)redoValue
{
if (lockIsLocked == YES)
{
undoRedoMoveAlert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedString(AlertViewText, nil)
message:nil
delegate:self
cancelButtonTitle:[NSString stringWithFormat:NSLocalizedString(AlertViewCancelButton, nil)]
otherButtonTitles:[NSString stringWithFormat:NSLocalizedString(AlertViewUnlockButton, nil)], nil];
[undoRedoMoveAlert show];
[undoRedoMoveAlert release];
}
else
{
[COLOR="Green"]//Toggle Undo Or Redo[/COLOR]
if ([toggle isEqualToString:@"undo"])
{
[COLOR="Green"]//Setup Redo Move[/COLOR]
[[undoManager prepareWithInvocationTarget:self] undoOrRedoMove:nil toPosition:redoMoveFloat withOpposingMoveValue:undoMoveFloat];
[undoManager setActionName:[NSString stringWithFormat:NSLocalizedString(MoveButtonLabel, nil)]];
}
[UIView beginAnimations:@"undoOrRedoMove" context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:kAnimationDuration];
[COLOR="Green"]//////Animation using floatPositionFromCenter float[/COLOR]
[UIView commitAnimations];
[COLOR="Green"]//Save New Position As Default[/COLOR]
[kDefaults setFloat:floatPositionFromCenter forKey:OriginPositionFromCenterKey];
}
}