如何在 Swift5 中监听 keydown 事件?
Posted
技术标签:
【中文标题】如何在 Swift5 中监听 keydown 事件?【英文标题】:How do I listen for a keydown event in Swift5? 【发布时间】:2020-02-12 21:27:59 【问题描述】:我试图在我的 MacOS 应用程序深处的 SwiftUI 视图中捕获 KeyDown 事件。但是,我什至无法在 AppDelegate 中触发一个。
这是我现在正在尝试的:
import Cocoa
import SwiftUI
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate
var window: NSWindow!
var settings = UserSettings()
func keyDown(theEvent: NSEvent)
if (theEvent.keyCode == 1)
print("test")
func applicationDidFinishLaunching(_ aNotification: Notification)
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView().environmentObject(settings)
// Create the window and set the content view.
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
func applicationWillTerminate(_ aNotification: Notification)
// Insert code here to tear down your application
我还能如何解决这个问题?
【问题讨论】:
这不是应用委托的工作......你应该在你的一个 VC 中实现keyDown
。
@Alexander-ReinstateMonica 不一定。你甚至可能没有窗户***.com/a/59592581/2303865
@LeoDabus 应用代理是否在响应者链中?
@Willeke developer.apple.com/library/archive/documentation/Cocoa/…
@LeoDabus See Responder Chain for Event Messages "第一个响应者通常是窗口中的“选定”视图对象,它的下一个响应者是它的包含视图(也称为它的父视图),依此类推直到NSWindow 对象。如果一个 NSWindowController 对象正在管理窗口,它将成为最终的下一个响应者。”。应用委托在哪里?
【参考方案1】:
您可以“安装”您自己的处理程序(参见 window.trackEvents ...)
import Cocoa
import SwiftUI
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification)
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
// Create the window and set the content view.
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
window.trackEvents(matching: .keyDown, timeout: .infinity, mode: RunLoop.Mode.default) (event, _) in
print(event)
func applicationWillTerminate(_ aNotification: Notification)
// Insert code here to tear down your application
这是一些打印示例
Optional(NSEvent: type=KeyDown loc=(116.223,179.594) time=38176.8 flags=0x100 win=0x11b830710 winNum=2404 ctxt=0x0 chars="h" unmodchars="h" repeat=0 keyCode=4)
Optional(NSEvent: type=KeyDown loc=(116.223,179.594) time=38178.2 flags=0x100 win=0x11b830710 winNum=2404 ctxt=0x0 chars="j" unmodchars="j" repeat=0 keyCode=38)
Optional(NSEvent: type=KeyDown loc=(116.223,179.594) time=38178.9 flags=0x100 win=0x11b830710 winNum=2404 ctxt=0x0 chars="h" unmodchars="h" repeat=0 keyCode=4)
Optional(NSEvent: type=KeyDown loc=(116.223,179.594) time=38179.4 flags=0x100 win=0x11b830710 winNum=2404 ctxt=0x0 chars="g" unmodchars="g" repeat=0 keyCode=5)
Optional(NSEvent: type=KeyDown loc=(116.223,179.594) time=38179.9 flags=0x100 win=0x11b830710 winNum=2404 ctxt=0x0 chars="h" unmodchars="h" repeat=0 keyCode=4)
Optional(NSEvent: type=KeyDown loc=(108.574,-175.18) time=38184.5 flags=0x100 win=0x11b830710 winNum=2404 ctxt=0x0 chars="m" unmodchars="m" repeat=0 keyCode=46)
Optional(NSEvent: type=KeyDown loc=(108.574,-175.18) time=38184.8 flags=0x100 win=0x11b830710 winNum=2404 ctxt=0x0 chars="," unmodchars="," repeat=0 keyCode=43)
Optional(NSEvent: type=KeyDown loc=(108.574,-175.18) time=38185.1 flags=0x100 win=0x11b830710 winNum=2404 ctxt=0x0 chars="." unmodchars="." repeat=0 keyCode=47)
请担心!这是最简单的例子,在实际应用程序中,您的处理程序必须处理所有 keyDown 事件!正如本例中所做的那样,默认操作(菜单...等)不会做出反应。您甚至必须从您的 Xcode(或终端)中停止应用程序,或者从系统菜单中强制退出它
【讨论】:
以上是关于如何在 Swift5 中监听 keydown 事件?的主要内容,如果未能解决你的问题,请参考以下文章