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

Handling shift+enter for newline, enter to send in TextEditor SwiftUI

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

我正在尝试一种使用 NSViewRepresentable 的方法来使用 AppKit 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) { }
}

然后我将其设置为 TextEditor 的 overlay/background(都尝试过),如下所示:

TextEditor(text: $message)
    .overlay(KeyEventHandling())
    ...more modifiers

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

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

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

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