SwiftUI:当我点击离开而不是按下 Return 时触发 onCommit

SwiftUI: onCommit triggered when is when I click away rather than press Return

我正在使用 onCommit 在 SwiftUI 中创建文本视图(该应用程序适用于 MacOS)。

struct TextBlockView: View {
     @State private var content = ""
    var id = UUID()

       var body: some View {

        let block = MacEditorTextView(text: $content, onEditingChanged: {
            print("editing changed")
        }, onCommit: {
            Keystroke.keystroke.enterPressed = true
            print("add new textblock here")
            //trigger function to create next block
           }).multilineTextAlignment(.leading)
               .frame(minWidth: 300,
                      maxWidth: .infinity,
                      minHeight: 40,
                      maxHeight: .infinity)
                .focusable()

        let tag = Rectangle()
                    .fill(Color.init(red: 1.00, green: 0.95, blue: 0.80, opacity: 1))
                    .frame(width: 10, height: 10)


        return HStack {
            tag
            block
        }
       }
}

当用户点击文本块以外的地方(添加新的文本块)时,会发生所需的操作。但是,我希望在用户点击 return 时发生此操作。当我第一次为 onCommit 编写代码时,它以这种方式工作了大约 30 分钟,然后才确定提交是单击而不是按下 return 键。

我尝试使用 "onCommand" 而不是 onCommit,但这没有用,而且我不确定我是否使用了合适的选择器。我还尝试在 NSWindow 级别按下回车键时进行捕获。但是,我认为这是不希望的,因为我不希望在按下回车键时执行此操作。

任何将 onCommit 与特定键 (return) 联系起来的帮助将不胜感激。

我是 Whosebug 的新手,所以如果需要更多信息,请告诉我。

你可以实现这样的东西。当您单击蓝色框时,它会发送一个单据来说明您有。将方框放在文本框后面。

快速剪切和粘贴,代码比您真正需要的多很多,您也可以对这个答案进行一些修剪。

import SwiftUI
import Combine

let saidNDone = PassthroughSubject<Void, Never>()

struct ContentView: View {
var body: some View {
    Example1()
}
}

struct Example1: View {
@State var viewState: CGSize = .zero
@State var dragState: CGSize = .zero
@State var touched = false

var body: some View {
    let dragGesture = DragGesture(minimumDistance: 0, coordinateSpace: CoordinateSpace.global)
        .onChanged { (value) in
            self.dragState = value.translation
    }.onEnded { (value) in
        self.viewState.width += value.translation.width
        self.viewState.height += value.translation.height
        self.dragState = .zero
        saidNDone.send()
    }
    return VStack {
        Rectangle().foregroundColor(.blue).frame(width: 100, height: 100)
        .offset(x: dragState.width + viewState.width,
                y: dragState.height + viewState.height)
        .gesture(dragGesture)
        Text("Hello World ")
          .onReceive(saidNDone) { ( _ ) in
            self.touched = true
          }
        .foregroundColor(self.touched ? Color.red: Color.black)
    }
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
    ContentView()
}
}

我能够解决我的问题不是使用 onCommit,而是在 NSTextView 包装器中包含这个函数:

        func textView(_ textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
             if (commandSelector == #selector(NSResponder.insertNewline(_:))) {
                            // Do something against ENTER key
                            print("enter")
                            //triggers function to create next block.
                            Keystroke.keystroke.enterPressed = true
                            return true
                        } else if (commandSelector == #selector(NSResponder.deleteForward(_:))) {
                            // Do something against DELETE key
                            return true
                        } else if (commandSelector == #selector(NSResponder.deleteBackward(_:))) {
                            // Do something against BACKSPACE key
                            return true
                        } else if (commandSelector == #selector(NSResponder.insertTab(_:))) {
                            // Do something against TAB key
                            return true
                        } else if (commandSelector == #selector(NSResponder.cancelOperation(_:))) {
                            // Do something against ESCAPE key
                            return true
                        }
            return false
        }

请注意,这是在符合 NSTextViewDelegate 和 NSControlTextEditingDelegate 协议的协调器中编写的。我不确定具体是哪一个导致它起作用。

如果以后有人遇到这个问题并且无意中发现了这个 post,请随时与我联系。