处理换行符的 shift+enter,在 TextEditor SwiftUI 中输入发送

Cry*_*thm 7 macos appkit swiftui

我正在尝试在文本框中处理换行符的shift+enter(聊天应用程序例如WhatsApp、Discord 等实现)。目前,我正在使用 SwiftUI TextEditor,但它没有任何方法可以像在 AppKit 中那样处理原始键盘事件。因此,一个黑客解决方案是检查消息的最后一个字符是否是 .onchange 中的换行符,然后发送消息。这种方法适用于“输入发送”,但我找不到在按下 Shift 键时不发送消息的方法(对于多行消息)。

我正在尝试一种使用NSViewRepresentableAppKit API 的方法,如下所示:

struct KeyEventHandling: NSViewRepresentable {
    class KeyView: NSView {
        override var acceptsFirstResponder: Bool { true }
        
        override func keyDown(with event: NSEvent) {
            print("keydown event")
        }

        override func flagsChanged(with event: NSEvent) {
            switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
            case [.shift]:
                print("shift key pressed")
            default:
                print("no modifier keys are pressed")
            }
        }
    }

    func makeNSView(context: Context) -> NSView {
        let view = KeyView()
        DispatchQueue.main.async { // wait till next event cycle
            view.window?.makeFirstResponder(view)
        }
        return view
    }

    func updateNSView(_ nsView: NSView, context: Context) { }
}
Run Code Online (Sandbox Code Playgroud)

然后我将其设置为文本编辑器的覆盖/背景(都尝试过),如下所示:

TextEditor(text: $message)
    .overlay(KeyEventHandling())
    ...more modifiers
Run Code Online (Sandbox Code Playgroud)

但是,它似乎只在文本编辑器未聚焦时处理事件。当 TextEditor(或似乎任何其他元素)获得焦点时,按 Shift 键不会调用 flagsChanged 覆盖。

除了将整个 TextEditor 重新实现为 之外,是否有更好的方法NSViewRepresentable来接收修饰键状态更改?谢谢!

mal*_*hal 2

换行的正确快捷方式实际上是 option+return 并且TextField支持它,例如

TextField("type something...", text: $text, onEditingChanged: { _ in     
    print("changed") 
}, onCommit: { 
    print("commit") 
})
Run Code Online (Sandbox Code Playgroud)