我正在整理一个自定义NSView,它通过绑定处理两个值。我正在Tom Dalling在问题Can you manually implement Cocoa bindings?中概述的更新时传播这些值。一切正常。
为了使控件不断更新,我更新并传播了-mouseDragged
方法中的值。再次,这工作正常,但它将中间步骤注册到NSUndoManager,我不想要。因此,我尝试在disableUndoRegistration
中发布-mouseDown
,然后在enableUndoRegistration
中发布mouseUp
。当然,我会再次更新并传播结果。
根本没有注册撤消,我意识到这是因为如果值不变,我的set函数不会注册撤消:
- (void)setX:(double)newX {
if (newX != x) {
[[undoManager prepareWithInvocationTarget:self] setX:x];
[self willChangeValueForKey:@"x"];
x = newX;
[self didChangeValueForKey:@"x"];
}
}
由于-mouseDragged
已经传播了该值,因此在-mouseUp
中再次发送时它没有更改,因此从未记录撤消。我当然希望它撤消到初始-mouseDown
之前的位置,所以让我说我通过将该值存储在控件中然后在-mouseUp
中再次发送该值来执行此操作新的价值。当然,这仍然存在一个问题,即我可以看到它恢复到原来的价值。
我可以通过检查撤消管理器是否已启用并跟踪旧值来在-setX:
方法中解决此问题。但是,我应该能够在控件内完成此操作,因为有控件具有这种确切的行为(就像NSSlider设置为连续)。
谢谢!
答案 0 :(得分:2)
您不能只使用beginUndoGrouping
和endUndoGrouping
吗?
P.S。如果你好奇Cocoa类是如何在内部工作的,那么检查GNUstep实现有时会有所帮助(NSUndoManager在GNUstep Base中,像NSSliderCell这样的AppKit类在GNUstep GUI中):