我试图在我的游戏中实现一个有两种模式的键盘类。游戏模式的输入使用小写且未修改的按键(未修改的意思是如果我在shift中输入"0",它仍然返回"0"而不是")")。我已经追踪到使用NSEvent
类的charactersIgnoringModifiers
方法,但该方法排除了除shift键以外的所有修饰符键。
您可以使用-[NSEvent keyCode]
,然后在不使用任何修饰符的情况下将关键代码转换为字符。后者说起来容易做起来难。这里有一个关于技巧和陷阱的长邮件列表。
到目前为止,我可以找到忽略<Shift>
修饰符的最佳选择是使用NSEvent.characters(byApplyingModifiers:)
与不改变键字形的修饰符,即.numericPad
:
func onKeyDown(event: NSEvent) {
let characters = event.characters(byApplyingModifiers: .numericPad)
print("Key pressed: (characters)")
}
理想情况下,你可以传入一个没有任何修饰符的掩码,但API似乎不支持。
为了完整起见,下面是如何开始编写一个函数,它接受一个UInt16
(CGKeyCode
),并根据用户的键盘返回一个字符串表示形式:
func keyCodeToString(code: UInt16) -> String {
switch code {
// Keys that are the same across keyboards
// TODO: Fill in the rest
case 0x7A: return "<F1>"
case 0x24: return "<Enter>"
case 0x35: return "<Escape>"
// Keys that change between keyboards
default:
let cgEvent = CGEvent(keyboardEventSource: nil, virtualKey: code, keyDown: true)!
let nsEvent = NSEvent(cgEvent: cgEvent)!
let characters = nsEvent.characters(byApplyingModifiers: .numericPad)
return String(characters?.uppercased() ?? "<KeyCode: (code)>")
}
}
我们的目标是让F1键显示<F1>
,而不是";在美国键盘上显示;
,而在西班牙键盘上显示Ñ
。