Cocoa:将动作(复制:、粘贴:等)转发到响应者链

Mic*_*eri 5 cocoa nsresponder responder-chain

我有一个子类NSOutlineView实现copy:,paste:,cut:等。另外,NSDocument子类实现这些相同的方法。

当大纲视图在响应者链中(是第一响应者或其父视图)时,所有复制/粘贴事件都NSOutlineView被子类拦截。我想要的是根据上下文捕获其中一些消息,或者让它们传播并NSDocument被子类捕获。

我想要的基本上是:

- (void)copy:(id)sender
{
    // If copy paste is enabled
    if ([self isCopyPasteEnabled]) {
        [[NSPasteboard generalPasteboard] clearContents];
        [[NSPasteboard generalPasteboard] writeObjects:self.selectedItems];
        return;
    }

    // If copy paste is disabled
    // ... forward copy: message to the next responder,
    // up to the NSDocument or whatever
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试了很多技巧,没有一个成功:

  • [[self nextResponder] copy:sender] 这不起作用,因为下一个响应者可能不会实施 copy:
  • [super copy:sender] 在这里一样, super 没有实现 copy:
  • [NSApp sendAction:anAction to:nil from:sender]向第一响应者发送一个动作是很好的。如果在动作中使用

当然,我可以在响应者链上手动循环,直到找到响应copy:或什至直接调用copy:当前文档的内容,但我正在寻找正确的方法。

提前谢谢了!

Ken*_*ses 3

这应该有效:

[[self nextResponder] tryToPerform:_cmd with:sender];
Run Code Online (Sandbox Code Playgroud)

但是,存在一个问题:响应者链中存在的响应者-copy:本身会导致启用“复制”菜单项,即使您的对象不在链中或没有执行-copy:。您的对象可以使用-validateMenuItem:或禁用该项目-validateUserInterfaceItem:,但是当且仅当链上存在另一个潜在目标并且该目标将启用该项目时,启用该项目将是很重要的。

另一种方法是,如果禁用粘贴板支持,则仅搜索实现操作方法的响应程序,并跳过大纲视图。覆盖-respondsToSelector:。如果选择器是粘贴板操作之一,并且禁用了粘贴板支持,则返回 false,即使您的类确实实现了它。也就是说,撒谎并声称您的对象只是不响应这些选择器。对于任何其他选择器,或者如果您的粘贴板支持已打开,请调用 super 并返回它返回的内容。