我有一个LSUIElement
显示菜单栏状态项的应用程序.应用程序可以显示包含文本字段的对话窗口.
如果用户右键单击/按住Control键并单击文本字段,则会出现一个菜单,允许剪切,复制,粘贴等.但是,标准的Command-X,Command-C和Command-V键盘快捷方式在领域.我假设这是因为我的应用程序没有提供定义了这些快捷方式的"编辑"菜单.
我已尝试将"编辑"菜单项添加到我的应用程序菜单中,如Ship Some Code博客中所述,但这不起作用.可以使用"编辑"菜单中的菜单项,但键盘快捷键仍然无法使用.
我可以想象一些破解键盘处理的方法,但是有一种"推荐"的方法可以让它工作吗?
(有关该应用程序的详细信息,请参阅菜单栏倒计时.)
相关问题:复制/粘贴在模态窗口中不起作用
改进CocoaRocket解决方案:
以下保存必须子类NSTextField并记住在整个应用程序中使用子类; 它还可以为处理它们的其他响应者启用复制,粘贴和朋友,例如.NSTextView.
将它放在NSApplication的子类中,并相应地更改Info.plist中的主体类.
- (void) sendEvent:(NSEvent *)event { if ([event type] == NSKeyDown) { if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask) { if ([[event charactersIgnoringModifiers] isEqualToString:@"x"]) { if ([self sendAction:@selector(cut:) to:nil from:self]) return; } else if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) { if ([self sendAction:@selector(copy:) to:nil from:self]) return; } else if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) { if ([self sendAction:@selector(paste:) to:nil from:self]) return; } else if ([[event charactersIgnoringModifiers] isEqualToString:@"z"]) { if ([self sendAction:@selector(undo:) to:nil from:self]) return; } else if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) { if ([self sendAction:@selector(selectAll:) to:nil from:self]) return; } } else if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == (NSCommandKeyMask | NSShiftKeyMask)) { if ([[event charactersIgnoringModifiers] isEqualToString:@"Z"]) { if ([self sendAction:@selector(redo:) to:nil from:self]) return; } } } [super sendEvent:event]; } // Blank Selectors to silence Xcode warnings: 'Undeclared selector undo:/redo:' - (IBAction)undo:(id)sender {} - (IBAction)redo:(id)sender {}
对我有用的是使用CocoaRocket 中的复制和粘贴键盘快捷键中提供的视图解决方案.
基本上,这意味着继承NSTextField并重写performKeyEquivalent:
.
更新: CocoaRocket网站显然已经消失了.这是Internet Archive链接:http://web.archive.org/web/20100126000339/http: //www.cocoarocket.com/articles/copypaste.html
编辑:Swift代码看起来像这样
class Editing: NSTextField { private let commandKey = NSEventModifierFlags.CommandKeyMask.rawValue private let commandShiftKey = NSEventModifierFlags.CommandKeyMask.rawValue | NSEventModifierFlags.ShiftKeyMask.rawValue override func performKeyEquivalent(event: NSEvent) -> Bool { if event.type == NSEventType.KeyDown { if (event.modifierFlags.rawValue & NSEventModifierFlags.DeviceIndependentModifierFlagsMask.rawValue) == commandKey { switch event.charactersIgnoringModifiers! { case "x": if NSApp.sendAction(Selector("cut:"), to:nil, from:self) { return true } case "c": if NSApp.sendAction(Selector("copy:"), to:nil, from:self) { return true } case "v": if NSApp.sendAction(Selector("paste:"), to:nil, from:self) { return true } case "z": if NSApp.sendAction(Selector("undo:"), to:nil, from:self) { return true } case "a": if NSApp.sendAction(Selector("selectAll:"), to:nil, from:self) { return true } default: break } } else if (event.modifierFlags.rawValue & NSEventModifierFlags.DeviceIndependentModifierFlagsMask.rawValue) == commandShiftKey { if event.charactersIgnoringModifiers == "Z" { if NSApp.sendAction(Selector("redo:"), to:nil, from:self) { return true } } } } return super.performKeyEquivalent(event) } }
编辑: Swift 3代码看起来像这样
class Editing: NSTextView { private let commandKey = NSEventModifierFlags.command.rawValue private let commandShiftKey = NSEventModifierFlags.command.rawValue | NSEventModifierFlags.shift.rawValue override func performKeyEquivalent(with event: NSEvent) -> Bool { if event.type == NSEventType.keyDown { if (event.modifierFlags.rawValue & NSEventModifierFlags.deviceIndependentFlagsMask.rawValue) == commandKey { switch event.charactersIgnoringModifiers! { case "x": if NSApp.sendAction(#selector(NSText.cut(_:)), to:nil, from:self) { return true } case "c": if NSApp.sendAction(#selector(NSText.copy(_:)), to:nil, from:self) { return true } case "v": if NSApp.sendAction(#selector(NSText.paste(_:)), to:nil, from:self) { return true } case "z": if NSApp.sendAction(Selector(("undo:")), to:nil, from:self) { return true } case "a": if NSApp.sendAction(#selector(NSResponder.selectAll(_:)), to:nil, from:self) { return true } default: break } } else if (event.modifierFlags.rawValue & NSEventModifierFlags.deviceIndependentFlagsMask.rawValue) == commandShiftKey { if event.charactersIgnoringModifiers == "Z" { if NSApp.sendAction(Selector(("redo:")), to:nil, from:self) { return true } } } } return super.performKeyEquivalent(with: event) } }
我和你有同样的问题,我想我已经找到了一个更简单的解决方案.您只需要将原始主菜单保留在MainMenu.xib中 - 它将不会显示,但所有操作都将得到正确处理.诀窍是它需要是原始的,如果你只是从库中拖动一个新的NSMenu,应用程序将不会将其识别为主菜单,我不知道如何标记它(如果你取消选中LSUIElement,你会发现它不会出现在顶部,如果它不是原始的那个).如果您已将其删除,则可以创建一个新的示例应用程序并从其NIB拖动菜单,这也适用.
当Caps Lock打开时,我已经改进了Adrian的解决方案:
- (void)sendEvent:(NSEvent *)event { if (event.type == NSKeyDown) { NSString *inputKey = [event.charactersIgnoringModifiers lowercaseString]; if ((event.modifierFlags & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask || (event.modifierFlags & NSDeviceIndependentModifierFlagsMask) == (NSCommandKeyMask | NSAlphaShiftKeyMask)) { if ([inputKey isEqualToString:@"x"]) { if ([self sendAction:@selector(cut:) to:nil from:self]) return; } else if ([inputKey isEqualToString:@"c"]) { if ([self sendAction:@selector(copy:) to:nil from:self]) return; } else if ([inputKey isEqualToString:@"v"]) { if ([self sendAction:@selector(paste:) to:nil from:self]) return; } else if ([inputKey isEqualToString:@"z"]) { if ([self sendAction:NSSelectorFromString(@"undo:") to:nil from:self]) return; } else if ([inputKey isEqualToString:@"a"]) { if ([self sendAction:@selector(selectAll:) to:nil from:self]) return; } } else if ((event.modifierFlags & NSDeviceIndependentModifierFlagsMask) == (NSCommandKeyMask | NSShiftKeyMask) || (event.modifierFlags & NSDeviceIndependentModifierFlagsMask) == (NSCommandKeyMask | NSShiftKeyMask | NSAlphaShiftKeyMask)) { if ([inputKey isEqualToString:@"z"]) { if ([self sendAction:NSSelectorFromString(@"redo:") to:nil from:self]) return; } } } [super sendEvent:event]; }
Thomas Kilian迅速解决方案3.
private let commandKey = NSEventModifierFlags.command.rawValue private let commandShiftKey = NSEventModifierFlags.command.rawValue | NSEventModifierFlags.shift.rawValue override func performKeyEquivalent(with event: NSEvent) -> Bool { if event.type == NSEventType.keyDown { if (event.modifierFlags.rawValue & NSEventModifierFlags.deviceIndependentFlagsMask.rawValue) == commandKey { switch event.charactersIgnoringModifiers! { case "x": if NSApp.sendAction(#selector(NSText.cut(_:)), to:nil, from:self) { return true } case "c": if NSApp.sendAction(#selector(NSText.copy(_:)), to:nil, from:self) { return true } case "v": if NSApp.sendAction(#selector(NSText.paste(_:)), to:nil, from:self) { return true } case "z": if NSApp.sendAction(Selector(("undo:")), to:nil, from:self) { return true } case "a": if NSApp.sendAction(#selector(NSResponder.selectAll(_:)), to:nil, from:self) { return true } default: break } } else if (event.modifierFlags.rawValue & NSEventModifierFlags.deviceIndependentFlagsMask.rawValue) == commandShiftKey { if event.charactersIgnoringModifiers == "Z" { if NSApp.sendAction(Selector(("redo:")), to:nil, from:self) { return true } } } } return super.performKeyEquivalent(with: event) }
Swift 4.2 for Thomas Kilian解决方案
class MTextField: NSSecureTextField { private let commandKey = NSEvent.ModifierFlags.command.rawValue private let commandShiftKey = NSEvent.ModifierFlags.command.rawValue | NSEvent.ModifierFlags.shift.rawValue override func performKeyEquivalent(with event: NSEvent) -> Bool { if event.type == NSEvent.EventType.keyDown { if (event.modifierFlags.rawValue & NSEvent.ModifierFlags.deviceIndependentFlagsMask.rawValue) == commandKey { switch event.charactersIgnoringModifiers! { case "x": if NSApp.sendAction(#selector(NSText.cut(_:)), to:nil, from:self) { return true } case "c": if NSApp.sendAction(#selector(NSText.copy(_:)), to:nil, from:self) { return true } case "v": if NSApp.sendAction(#selector(NSText.paste(_:)), to:nil, from:self) { return true } case "z": if NSApp.sendAction(Selector(("undo:")), to:nil, from:self) { return true } case "a": if NSApp.sendAction(#selector(NSResponder.selectAll(_:)), to:nil, from:self) { return true } default: break } } else if (event.modifierFlags.rawValue & NSEvent.ModifierFlags.deviceIndependentFlagsMask.rawValue) == commandShiftKey { if event.charactersIgnoringModifiers == "Z" { if NSApp.sendAction(Selector(("redo:")), to:nil, from:self) { return true } } } } return super.performKeyEquivalent(with: event) } }