如果满足以下条件,我发现它可以工作:
0) 为 UIKeyCommands 的简单构建创建一个结构
struct keyCommand {
var input: String;
var modifiers: UIKeyModifierFlags
}
`
1) 子类 UIWINdow
2)您覆盖“场景窗口”中的 keyCommands 变量,并为您希望窗口捕获的每个键创建键命令。我的应用程序有多个场景,所以我保存的场景 ID 字符串用于显示当前焦点(第一响应者)
class Window: UIWindow{
var model: CCModel! // will load after the window established
var app: AppDelegate!
var scene: String!
var keyCommandList: [keyCommand]
var commands: [UIKeyCommand]?
override init(frame: CGRect) {
keyCommandList = [
//arrow keys
keyCommand(input: UIKeyCommand.inputUpArrow, modifiers:[]),
keyCommand(input: UIKeyCommand.inputUpArrow, modifiers:.alternate),
keyCommand(input: UIKeyCommand.inputUpArrow, modifiers:.command),
keyCommand(input: UIKeyCommand.inputUpArrow, modifiers: .shift),
keyCommand(input: UIKeyCommand.inputDownArrow, modifiers:[]),
keyCommand(input: UIKeyCommand.inputDownArrow, modifiers:.alternate),
keyCommand(input: UIKeyCommand.inputDownArrow, modifiers:.command),
keyCommand(input: UIKeyCommand.inputDownArrow, modifiers: .shift),
keyCommand(input: UIKeyCommand.inputLeftArrow, modifiers:[]),
keyCommand(input: UIKeyCommand.inputLeftArrow, modifiers:.alternate),
keyCommand(input: UIKeyCommand.inputLeftArrow, modifiers:.command),
keyCommand(input: UIKeyCommand.inputLeftArrow, modifiers: .shift),
keyCommand(input: UIKeyCommand.inputRightArrow, modifiers:[]),
keyCommand(input: UIKeyCommand.inputRightArrow, modifiers:.alternate),
keyCommand(input: UIKeyCommand.inputRightArrow, modifiers:.command),
keyCommand(input: UIKeyCommand.inputRightArrow, modifiers: .shift),
//escape
keyCommand(input: UIKeyCommand.inputEscape, modifiers: []),
// a (play arpegio), A - progression arpegio
keyCommand(input: "a", modifiers: []),
keyCommand(input: "a", modifiers: .shift),
// c (play chord), S - progression chord
keyCommand(input: "c", modifiers: []),
keyCommand(input: "c", modifiers: .shift),
// tab key,
keyCommand(input: "\t", modifiers: []),
keyCommand(input: "\t", modifiers: .shift),
// return
keyCommand(input: "\r", modifiers: []),
keyCommand(input: "\r", modifiers: .shift),
// +
keyCommand(input: "+", modifiers: []),
keyCommand(input: "=", modifiers: []),
// -
keyCommand(input: "-", modifiers: []),
keyCommand(input: "_", modifiers: []),
// space
keyCommand(input: " ", modifiers: []),
keyCommand(input: "0", modifiers: []), // toggle the accents
keyCommand(input: "p", modifiers: []),
keyCommand(input: "s", modifiers: []),
keyCommand(input: "s", modifiers: .alternate),
keyCommand(input: "s", modifiers: .command),
keyCommand(input: "i", modifiers: []),
keyCommand(input: "k", modifiers: []),
keyCommand(input: "?", modifiers: []),
keyCommand(input: "t", modifiers: []),
keyCommand(input: "r", modifiers: []),
keyCommand(input: "o", modifiers: []),
keyCommand(input: "d", modifiers: []),
keyCommand(input: "w", modifiers: []),
keyCommand(input: "h", modifiers: []),
keyCommand(input: "l", modifiers: []),
keyCommand(input: "1", modifiers: []),
keyCommand(input: "2", modifiers: []),
keyCommand(input: "3", modifiers: []),
keyCommand(input: "4", modifiers: []),
keyCommand(input: "5", modifiers: []),
]
self.commands = []
for command in self.keyCommandList {
let keycommand = UIKeyCommand(input: command.input, modifierFlags: command.modifiers, action: #selector(self.captureKey(sender:)))
self.commands!.append(keycommand)
}
super.init(frame: frame)
open override var keyCommands: [UIKeyCommand]? {
return self.commands
}
@objc func captureKey(sender: UIKeyCommand) {
self.model.onKeyCapture(sender, scene: self.scene)
}
}
3) 将捕获的键和修饰符发送给委托来管理它。在我的情况下,这是方法 self.model.method。 (模型是这个应用程序的单例类)。
func onKeyCapture(_ sender: UIKeyCommand, scene: String) {
let app = getApp()
let input = sender.input
let modifiers = sender.modifierFlags
if scene == "main" {
// handle main screen key commands
// mode independent commands
switch input {
case "k","1":
setMode(value: "C")
selectSegment(0)
return
case "s","2":
if modifiers == [] { // allow modified "s" through
setMode(value: "S")
selectSegment(1)
return
}
case "i","?","3":
setMode(value: "I")
selectSegment(2)
return
case "p","4":
setMode(value: "P")
selectSegment(3)
return
default:
break
}
switch input {
case "t":
switch modifiers {
case []:
playTuning()
return
default:
break
}
default:
break
}
switch mode {
case "C": // chord mode
switch input {
case UIKeyCommand.inputUpArrow:
switch modifiers {
case []:
nextPrev(type: .prev)
default:
break
}
case UIKeyCommand.inputDownArrow:
switch modifiers {
case []:
nextPrev(type: .next)
default:
break
}
case UIKeyCommand.inputRightArrow:
switch modifiers {
case []:
app.chordTVC!.setbyKeyCommand(delta: +1)
default:
break
}
case UIKeyCommand.inputLeftArrow:
switch modifiers {
case []:
app.chordTVC!.setbyKeyCommand(delta: -1)
default:
break
}
case " ":
toggleShowChordScale()
case "0":
app.fretboardVC!.toggleAccents()
case "c":
switch modifiers {
case []:
playChord()
default:
break
}
case "a":
switch modifiers {
case []:
playArpeggio()
default:
break
}
case "+","=":
if root == nil { // no root chosen, so set it to "C"
app.rootTVC!.setRootByValue(key: "C")
} else { // raise the key a semitone
incrementDecrementKey(direction: 1)
}
case "-","_":
if root == nil { // no root chosen, so set it to "C"
app.rootTVC!.setRootByValue(key: "C")
} else { // lower the key a semitone
incrementDecrementKey(direction: -1)
}
case "r":
app.filtersCVC!.toggleFilter("NOROOT_OK")
case "5":
app.filtersCVC!.toggleFilter("NO5TH_OK")
case "o":
app.filtersCVC!.toggleFilter("NO_OPEN")
case "d":
app.filtersCVC!.toggleFilter("NO_DEAD")
case "w":
app.filtersCVC!.toggleFilter("NO_WIDOW")
case "h":
app.filtersCVC!.toggleHighLow("high")
case "l":
app.filtersCVC!.toggleHighLow("low")
default:
break
}
case "S": // Scale mode
switch input {
case UIKeyCommand.inputRightArrow:
switch modifiers {
case []:
app.scaleTVC!.setbyKeyCommand(delta: +1)
default:
break
}
case UIKeyCommand.inputLeftArrow:
switch modifiers {
case []:
app.scaleTVC!.setbyKeyCommand(delta: -1)
default:
break
}
case "+","=":
if root == nil { // no root chosen, so set it to "C"
app.rootTVC!.setRootByValue(key: "C")
} else { // raise the key a semitone
incrementDecrementKey(direction: 1)
}
case "-","_":
if root == nil { // no root chosen, so set it to "C"
app.rootTVC!.setRootByValue(key: "C")
} else { // lower the key a semitone
incrementDecrementKey(direction: -1)
}
case " ":
switch modifiers {
case []: // two finger tap equivalent
if scaleDisplayMode == "notes" {
scaleDisplayMode = "tones"
} else {
scaleDisplayMode = "notes"
}
FretboardNeedsDisplay()
default:
break
}
case "a":
showAccents = !showAccents
FretboardNeedsDisplay()
case "\r":
if modifiers == []{
playScale()
}
default:
break
}
case "I": // Identify mode
switch input {
default:
break
}
case "P": // Progression mode
switch input {
case UIKeyCommand.inputUpArrow:
switch modifiers {
case []:
nextPrev(type: .prev)
default:
break
}
case UIKeyCommand.inputDownArrow:
switch modifiers {
case []:
nextPrev(type: .next)
default:
break
}
case UIKeyCommand.inputRightArrow: // next previous progression
switch modifiers {
case []:
app.progDisplayTVC!.setbyKeyCommand(delta: +1)
default:
break
}
case UIKeyCommand.inputLeftArrow:
switch modifiers {
case []:
app.progDisplayTVC!.setbyKeyCommand(delta: -1)
default:
break
}
case " ":
toggleShowChordScale()
case "0":
app.fretboardVC!.toggleAccents()
case "c":
switch modifiers {
case []:
playChord()
case .shift:
progPlayChord()
default:
break
}
case "a":
switch modifiers {
case []:
playArpeggio()
case .shift:
progPlayArp()
default:
break
}
case "+","=":
if root == nil { // no root chosen, so set it to "C"
app.rootTVC!.setRootByValue(key: "C")
} else { // raise the key a semitone
incrementDecrementKey(direction: 1)
}
case "-","_":
if root == nil { // no root chosen, so set it to "C"
app.rootTVC!.setRootByValue(key: "C")
} else { // lower the key a semitone
incrementDecrementKey(direction: -1)
}
case "r":
app.filtersCVC!.toggleFilter("NOROOT_OK")
case "5":
app.filtersCVC!.toggleFilter("NO5TH_OK")
case "o":
app.filtersCVC!.toggleFilter("NO_OPEN")
case "d":
app.filtersCVC!.toggleFilter("NO_DEAD")
case "w":
app.filtersCVC!.toggleFilter("NO_WIDOW")
case "h":
app.filtersCVC!.toggleHighLow("high")
case "l":
app.filtersCVC!.toggleHighLow("low")
default:
break
}
default:
break
}
}
else if scene == "help" {
// handle help screen key commands
}
}