捕获 NSTextView 的所有选择更改事件,包括由鼠标拖动引起的事件

问题描述

我有一个 NSViewRepresentable,其中包含一个 NSScrollView,里面有一个 NSTextView

struct MultilineTextField: NSViewRepresentable {
    typealias NSViewType = NSScrollView
    private let scrollView = NSScrollView()
    private let textView = NSTextView()
    @Binding var text: String
    @Binding var loc: NSRange
    func makeNSView(context: Context) -> NSScrollView {
        textView.string = text
        textView.delegate = context.coordinator
        scrollView.documentView = textView
        return scrollView
    }
    func updateNSView(_ scrollView: NSScrollView,context: Context) {}
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
    class Coordinator: NSObject,NSTextViewDelegate {
        let textField: MultilineTextField
        init(_ textField: MultilineTextField) {
            self.textField = textField
        }
        func textDidChange(_ notification: Notification) {
            textField.text = textField.textView.string
        }
        func textViewDidChangeSelection(_ notification: Notification) {
            dispatchQueue.main.async {
                self.textField.loc = self.textField.textView.selectedRange()
            }
        }
    }
}

我正在尝试提取要在不同视图中显示selectedRangeNSTextView,例如:

Text(String(loc.location))

当使用箭头键更改 selectedRange 以及鼠标向下和鼠标向上时它可以工作,但是在将鼠标拖到文本上的过程中似乎没有调用 textViewDidChangeSelection .因此,拖动时显示loc.location 值不会改变,直到鼠标抬起。

作为一种解决方法,我尝试将 NSTextView 子类化以覆盖 mouseMoved 方法,但由于某种原因,它似乎也没有被调用

为了验证 selectedRange 实际上在鼠标拖动时得到更新,我尝试不断更新 loc(这是在 Coordinator 类中):

init(_ textField: MultilineTextField) {
    self.textField = textField
    super.init()
    updateSelection()
}
func updateSelection() {
    dispatchQueue.main.async {
        self.textField.loc = self.textField.textView.selectedRange()
        self.updateSelection()
    }
}

代码确实有效,但也无缘无故地使用了 100% 的 cpu

有没有办法在鼠标拖动的情况下selectedRange发生变化时得到通知

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)