Geo*_*e_E 8 macos keyboard-events ios swift swiftui
我想要响应按键,例如esc
macOS/OSX 上的按键以及在 iPad 上使用外部键盘时的按键。我怎样才能做到这一点?
我曾想过将@available
/#available
与 SwiftUI 一起使用onExitCommand
,这看起来很有前途,但不幸的是这只适用于 macOS/OSX。除了 macOS/OSX 之外,如何响应 SwiftUI 中的按键操作?
在 macOS 和 tvOS 上有一个onExitCommand(perform:)
视图修饰符。来自苹果的文档:
设置在视图具有焦点时响应接收退出命令而触发的操作。
用户通过按 tvOS 上的菜单按钮或 macOS 上的退出键来生成退出命令。
例如:
struct ContentView: View {
var body: some View {
VStack {
TextField("Top", text: .constant(""))
.onExitCommand(perform: {
print("Exit from top text field")
})
TextField("Bottom", text: .constant(""))
.onExitCommand(perform: {
print("Exit from bottom text field")
})
}
.padding()
}
}
Run Code Online (Sandbox Code Playgroud)
.keyboardShortcut(_:modifiers:)
.感谢@Asperi为我指明了正确的方向,我现在已经成功地完成了这项工作。
解决方案是使用UIKeyCommand
. 这是我所做的,但您可以根据自己的情况进行不同的调整。
我有一个@EnvironmentObject
Called AppState
,它可以帮助我设置委托,因此它们的键盘输入可能会有所不同,具体取决于当前显示的视图。
protocol KeyInput {
func onKeyPress(_ key: String)
}
class KeyInputController<Content: View>: UIHostingController<Content> {
private let state: AppState
init(rootView: Content, state: AppState) {
self.state = state
super.init(rootView: rootView)
}
@objc required dynamic init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func becomeFirstResponder() -> Bool {
true
}
override var keyCommands: [UIKeyCommand]? {
switch state.current {
case .usingApp:
return [
UIKeyCommand(input: UIKeyCommand.inputEscape, modifierFlags: [], action: #selector(keyPressed(_:)))
]
default:
return nil
}
}
@objc private func keyPressed(_ sender: UIKeyCommand) {
guard let key = sender.input else { return }
state.delegate?.onKeyPress(key)
}
}
Run Code Online (Sandbox Code Playgroud)
应用程序状态 ( @EnvironmentObject
):
class AppState: ObservableObject {
var delegate: KeyInput?
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
场景委托看起来像这样:
let stateObject = AppState()
let contentView = ContentView()
.environmentObject(stateObject)
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = KeyInputController(rootView: contentView, state: stateObject)
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
这使得现在根据按下的键添加功能变得非常容易。
符合KeyInput
,例如:
struct ContentView: View, KeyInput {
/* ... */
var body: some View {
Text("Hello world!")
.onAppear {
self.state.delegate = self
}
}
func onKeyPress(_ key: String) {
print(key)
guard key == UIKeyCommand.inputEscape else { return }
// esc key was pressed
/* ... */
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9813 次 |
最近记录: |