SwiftUI:onCommit在我单击而不是按Return时触发

时间:2020-05-29 01:09:01

标签: textview swiftui keystroke

我正在与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
        }
       }
}

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

我尝试使用“ onCommand”代替onCommit,但这没有用,并且我不确定是否使用了适当的选择器。我还尝试捕获在NSWindow级别按下Enter键时的情况。但是,我决定不希望这样做,因为我不希望每当按下Enter键时都会执行此操作。

对于将onCommit与特定键(返回)相关联的任何帮助,将非常感谢。

我是StackOverflow的新手,所以让我知道是否需要更多信息。

2 个答案:

答案 0 :(得分:0)

您可以实现这样的事情。当您单击蓝色框时,它会发送一个单据以表明您已拥有。将框放在文本框后面。

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

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()
}
}

答案 1 :(得分:0)

我无法通过使用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协议的协调器中编写的。我不确定是哪一个导致它正常工作。

如果将来有人遇到这个问题并且偶然发现了这篇文章,请随时与我联系。