我正在组合一个自定义 NSView,它通过绑定(bind)处理两个值。正如 Tom Dalling 在问题 Can you manually implement Cocoa bindings? 中概述的那样,我正在根据更新传播这些值.这一切都很好。
为了使控件不断更新,我更新并传播了 -mouseDragged
方法中的值。同样,这工作正常,但它将中间步骤注册到 NSUndoManager,这是我不想要的。因此,我尝试在 -mouseDown
中发出 disableUndoRegistration
,然后在 mouseUp
中发出 enableUndoRegistration
。我自然会再次更新和传播结果。
根本没有注册撤消,我意识到这是因为如果值不变,我的 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)。
谢谢!
最佳答案
你不能只使用 beginUndoGrouping
和 endUndoGrouping
吗?
附言如果您对 Cocoa 类的内部工作方式感到好奇,检查 GNUstep 实现有时会有所帮助(NSUndoManager 在 GNUstep Base 中,AppKit 类如 NSSliderCell 在 GNUstep GUI 中):
关于objective-c - 使用适当的撤消管理创建持续更新的自定义控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5913421/