Cocoa 防止Escape键用关闭框关闭NSPanel
是否有人知道防止逃生钥匙在钥匙窗口关闭Cocoa 防止Escape键用关闭框关闭NSPanel,cocoa,nswindow,nspanel,responder-chain,Cocoa,Nswindow,Nspanel,Responder Chain,是否有人知道防止逃生钥匙在钥匙窗口关闭NSPanel的最佳方法?我的面板是一个子窗口,我希望它的行为更像窗口的半永久部分,更像抽屉,对于其中的文本控件,我希望使用Escape键取消编辑 我最近在Cocoa文档中找到了更多关于windows和Escape键的信息。在nsrresponder类参考中,在cancelOperation:下,其中显示“窗口将cancelOperation:的默认操作消息发送到第一个响应程序,消息从那里沿响应程序链向上传递”。对于NSPanel,情况似乎有所不同,窗口关闭
NSPanel
的最佳方法?我的面板是一个子窗口,我希望它的行为更像窗口的半永久部分,更像抽屉,对于其中的文本控件,我希望使用Escape键取消编辑
我最近在Cocoa文档中找到了更多关于windows和Escape键的信息。在nsrresponder类参考中,在cancelOperation:
下,其中显示“窗口将cancelOperation:
的默认操作消息发送到第一个响应程序,消息从那里沿响应程序链向上传递”。对于NSPanel
,情况似乎有所不同,窗口关闭时,第一响应者未获得取消操作:
调用或NSTextView代理获得其doCommandBySelector:
调用
考虑到我一直在做OSX工作,我对应答器链的输入和输出的了解是可耻的。我在想,我需要在我的NSPanel
子类中设置keyDown:
,使其行为类似于普通窗口。我尝试覆盖NSPanel
,可以捕捉到keyDown:
,将呼叫转发到NSWindow的keyDown:
,而不是super
,但没有任何更改,Escape仍然关闭了窗口,没有向第一响应者发送消息。这样做合理吗
然后,我尝试完全重新实现我的面板子类“keyDown:
”,使它可以这样做:
[self.firstResponder cancelOperation:self]
我想这会让我的文本字段按照它通常期望的方式处理转义,如果没有文本字段作为第一响应者,那么调用可能会死路一条。然而,我试过了,面板像以前一样关闭了。显然,我没有在正确的水平上截取东西
是否有人知道在低级别按键事件和面板关闭之间运行的方法序列,或者我需要覆盖什么来拦截它并确保取消操作:
转到我的第一响应者?在nib或代码中的某个地方,将您的NSTableView委托设置为控制器
请注意,setDelegate:与setDatasource:不同
就我而言:
@接口值编辑器:NSObject
+ (ValueEditorCmdType)cmdTypeForSelector:(SEL)command
{
ValueEditorCmdType cmdType = kCmdTypeNone;
if ( command == @selector(insertLineBreak:) || command == @selector(insertNewline:) || command == @selector(insertNewlineIgnoringFieldEditor:) || command == @selector(insertParagraphSeparator:))
cmdType = kCmdTypeAccept;
else if ( command == @selector(insertTab:) || command == @selector(selectNextKeyView:) || command == @selector(insertTabIgnoringFieldEditor:))
cmdType = kCmdTypeNext;
else if ( command == @selector(insertBacktab:) || command == @selector(selectPreviousKeyView:))
cmdType = kCmdTypePrev;
else if ( command == @selector(cancelOperation:) )
cmdType = kCmdTypeCancel;
return cmdType;
}
#pragma mark - NSControl delegate
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command
{
ValueEditorCmdType cmdType = [ValueEditor cmdTypeForSelector:command];
if ( cmdType == kCmdTypeCancel )
{
[control abortEditing];
// when user hits 'ESC' key with a field editor active, cancel the field editor,
// but return YES here so that NSPanel doesn't close.
// Hitting 'ESC' a 2nd time will close the NSPanel.
return YES;
}
return NO;
}
基思·克努伯的答案是:
class ValueEditor : NSObject, NSControlTextEditingDelegate {
enum CommandType {
case none
case accept
case next
case prev
case cancel
}
class func commandTypeType(for command: Selector) -> CommandType {
let commandType: CommandType
switch command {
case #selector(NSStandardKeyBindingResponding.insertLineBreak(_:)) :
fallthrough
case #selector(NSStandardKeyBindingResponding.insertNewline(_:)) :
fallthrough
case #selector(NSStandardKeyBindingResponding.insertNewlineIgnoringFieldEditor(_:)) :
fallthrough
case #selector(NSStandardKeyBindingResponding.insertParagraphSeparator(_:)) :
commandType = .accept
case #selector(NSStandardKeyBindingResponding.insertTab(_:)) :
fallthrough
case #selector(NSWindow.selectNextKeyView(_:)) :
fallthrough
case #selector(NSStandardKeyBindingResponding.insertTabIgnoringFieldEditor(_:)) :
commandType = .next
case #selector(NSStandardKeyBindingResponding.insertBacktab(_:)) :
fallthrough
case #selector(NSWindow.selectPreviousKeyView(_:)) :
commandType = .prev
case #selector(NSStandardKeyBindingResponding.cancelOperation(_:)) :
commandType = .cancel
default:
commandType = .none
}
return commandType
}
// MARK: - NSControl delegate
func control(_ control: NSControl,
textView: NSTextView,
doCommandBy commandSelector: Selector) -> Bool {
let commandType: CommandType = ValueEditor.commandTypeType(for: commandSelector)
switch commandType {
case .cancel:
control.abortEditing()
// When the user hits 'ESC' key with a field editor active, cancel the field editor,
// but return `true` here so that the NSPanel doesn’t close.
// Hitting 'ESC' a second time will close the NSPanel.
return true
default:
return false
}
}
}
不要忘记将ValueEditor实例设置为NSTextView对象的委托