3

我正在组合一个通过绑定处理两个值的自定义 NSView。我在更新时传播值,如 Tom Dalling 在问题中您可以手动实现 Cocoa 绑定吗?. 这一切都很好。

为了使控件不断更新,我更新并传播了-mouseDragged方法中的值。同样,这工作正常,但它将中间步骤注册到 NSUndoManager,这是我不想要的。所以,我尝试发出disableUndoRegistrationin-mouseDown然后enableUndoRegistrationmouseUp. 自然我会再次更新和传播结果。

根本没有注册撤消,我意识到这是因为如果值不变,我的 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)。

谢谢!

4

1 回答 1

2

你不能只使用beginUndoGroupingandendUndoGrouping吗?


PS 如果你好奇 Cocoa 类是如何在内部工作的,检查一下 GNUstep 实现有时会很有帮助(NSUndoManager 在 GNUstep Base 中,像 NSSliderCell 这样的 AppKit 类在 GNUstep GUI 中):

http://wwwmain.gnustep.org/resources/downloads.php?site=http%3A%2F%2Fftpmain.gnustep.org%2Fpub%2Fgnustep%2F#core

于 2011-05-08T21:02:52.760 回答