Search code examples
textviewswiftuikeystroke

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


I am working with onCommit for a text view in SwiftUI (the app is for 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
        }
       }
}

The desired action occurs when the user clicks away from the text block (a new textblock is added). However, I would like this action to occur when the user hits return. It worked this way for about 30 minutes when I first wrote the code for onCommit, before it decided a commit was a click rather than press of the return key.

I have tried to use the "onCommand" instead of onCommit, but this did not work, and I am unsure if I used the appropriate selector. I have also tried to capture when the enter key is pressed at the level of the NSWindow. However, I decided this was not desired, as I do not wish for this action to take place whenever the enter key is pressed.

Any help in relating onCommit to a specific key (return) would be very appreciated.

I am new to StackOverflow, so let me know if more information is needed.


Solution

  • I was able to fix my issue not by using onCommit, but rather including this function in the NSTextView wrapper:

            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
            }
    

    Note, this was written in a coordinator that conformed to the NSTextViewDelegate and NSControlTextEditingDelegate protocols. I'm not exactly sure which one specifically caused it to work.

    If anyone faces this issue in the future and stumbles upon this post, do not hesitate to reach out to me.