我有一个NSView对象,它带有mouseDragged事件,该事件会更改在其相应视图中绘制的对象的位置。然后在我的NSViewController类中,它检索该新位置并将该新值分配给我的模型数据对象。换句话说,每次 调用mouseDragged事件时,ViewController都会更新新位置。因此,在同一范围内,ViewController通过NSUndoManager注册撤消事件,以允许用户执行撤消操作。
在撤消管理器中注册了多个position-update-actions时,就会出现此问题。当用户执行撤消操作时,其余操作也将撤消,而不仅仅是从撤消堆栈中弹出最近的操作。
作为参考,这是我的代码:
// MyViewController.m
- (void)translateObject:(double)dx
withYPosition:(double)dy
{
NSMutableDictionary* transformData = [self.transformData transform];
double t_x = [[transformData objectForKey:@"translate_x"] doubleValue];
double t_y = [[transformData objectForKey:@"translate_y"] doubleValue];
t_x -= x;
t_y -= y;
[self translateShape:@[[NSNumber numberWithDouble:t_x],[NSNumberNumberWithDouble:t_y]]];
}
- (void)translateShape:(NSArray*)val
{
NSMutableDictionary* transformData = [self.transformData transform];
double old_t_x = [[transformData objectForKey:@"translate_x"] doubleValue];
double old_t_y = [[transformData objectForKey:@"translate_y"] doubleValue];
double t_x = [[val objectAtIndex:0] doubleValue];
double t_y = [[val objectAtIndex:1] doubleValue];
[transformData setObject:[NSNumber numberWithDouble:t_x] forKey:@"translate_x"];
[transformData setObject:[NSNumber numberWithDouble:t_y] forKey:@"translate_y"];
[self.transformData setTransform:transformData];
[self.glView setNeedsDisplay:YES];
[[self undoManager] registerUndoWithTarget:self
selector:@selector(translateShape:)
object:@[[NSNumber numberWithDouble:old_t_x],
[NSNumber numberWithDouble:old_t_y]]];
[[self undoManager] setActionName:@"Shape Drag Move"];
}
/* * * I have also done this:
- (void)translateShape:(NSArray*)val
{
NSMutableDictionary* transformData = [self.transformData transform];
double old_t_x = [[transformData objectForKey:@"translate_x"] doubleValue];
double old_t_y = [[transformData objectForKey:@"translate_y"] doubleValue];
double t_x = [[val objectAtIndex:0] doubleValue];
double t_y = [[val objectAtIndex:1] doubleValue];
[transformData setObject:[NSNumber numberWithDouble:t_x] forKey:@"translate_x"];
[transformData setObject:[NSNumber numberWithDouble:t_y] forKey:@"translate_y"];
[self.transformData setTransform:transformData];
[self.glView setNeedsDisplay:YES];
[[self undoManager] registerUndoWithTarget:self
selector:@selector(unTranslateShape:)
object:@[[NSNumber numberWithDouble:old_t_x],
[NSNumber numberWithDouble:old_t_y]]];
[[self undoManager] setActionName:@"Shape Drag Move"];
}
- (void)unTranslateShape:(NSArray*)val
{
NSMutableDictionary* transformData = [self.transformData transform];
double old_t_x = [[transformData objectForKey:@"translate_x"] doubleValue];
double old_t_y = [[transformData objectForKey:@"translate_y"] doubleValue];
double t_x = [[val objectAtIndex:0] doubleValue];
double t_y = [[val objectAtIndex:1] doubleValue];
[transformData setObject:[NSNumber numberWithDouble:t_x] forKey:@"translate_x"];
[transformData setObject:[NSNumber numberWithDouble:t_y] forKey:@"translate_y"];
[self.transformData setTransform:transformData];
[self.glView setNeedsDisplay:YES];
[[self undoManager] registerUndoWithTarget:self
selector:@selector(translateShape:)
object:@[[NSNumber numberWithDouble:old_t_x],
[NSNumber numberWithDouble:old_t_y]]];
[[self undoManager] setActionName:@"Shape Redo Drag Move"];
}
* * */
下面是一张我做得不好的图,它说明了我预期的撤消操作与我实际观察到的情况:
有人可以阐明这一点吗?谢谢。
答案 0 :(得分:0)
感谢James Bucanek关于设置NSUndoManager的runLoopModes的提示,我能够弄清楚为什么NSUndoManager会在mouseDown,mouseDragged和mouseUp事件期间撤消所有已注册的撤消。事实证明,NSUndoManager将事件(我想这也意味着在mouseDragged事件中注册的所有撤消操作)注册的所有撤消进行分组。为了在您的NSView子类中简单地注册撤消操作,应该执行以下操作:
/** Simple case: Everything handled by NSView subclass **/
- (void)mouseDown:(NSEvent *)event
{
// Set your undo manager's groupsByEvent property to NO here
}
- (void)mouseDragged:(NSEvent *)event
{
// Tell your undo manager to begin grouping
// Register undo and redo actions here
// Tell your undo manager to end grouping
}
- (void)mouseUp:(NSEvent *)event
{
// Set your undo manager's groupsByEvent property to YES here
}
由于我使用协议在视图控制器中设置模型的属性,因此我仅实现了另一种方法,该协议在NSView的mouseDown / mouseUp事件期间调用,随后将GroupsByEvent设置为NO和YES。如果有人知道该问题的更好的实现/解决方案,请随时纠正我。希望这会有所帮助!