NSTextView使用自定义属性拖动文本

时间:2017-08-16 11:57:20

标签: swift macos nstextview

我的NSTextView子类有问题。我的视图包含带有自定义属性的属性字符串,因此我必须实现以下粘贴板方法,以确保将我的自定义属性复制到粘贴板上。

writeSelection(to:type:)
readSelection(from:type:)

在readSelection中,我手动读取粘贴板上的字符串,并将其写入到RangeForUserTextChange的NSTextView的textStorage中。

override func readSelection(from pboard: NSPasteboard, type: String) -> Bool {


    // Manually reads the text on the pasteboard, and write it to textStorage

    if type == astroBoardAttributedString {

        if let string = pboard.string(forType: astroBoardAttributedString) {

            let attrString = NSAttributedString(string: string)

            self.textStorage?.replaceCharacters(in: self.rangeForUserTextChange, with: attrString)


            return true

        }


    }

    return super.readSelection(from: pboard, type: type)

}

现在的问题是,当我从第5行到第1行下选择并向上拖动文本时,文本正确地插入第1行,然后系统会尝试从第5行删除文本,其中现在包含第4行,因为在第1行下面添加了一个额外的行。

enter image description here

/*
line 1 <-- Drop after this line
line 2
line 3
line 4
line 5 <-- Drag from this line

The expected outcome is 

line 1
line 5
line 2
line 3
line 4

The actual resulting outcome is 

line 1
line 5
line 2
line 3
line 5

What happens is

line 1
line 5  <-- Line inserted here (correct)
line 2
line 3
line 4 <-- This line is removed instead :(
line 5 <-- This is the line that should be removed.
*/

如您所见,系统在更改长度后删除了该行。当拖放方法删除从textview拖动的textStorage中的文本时,我找不到任何用于拦截的委托方法。

1 个答案:

答案 0 :(得分:2)

在联系Apple寻求支持后,我得到了答案,这里是引用。

  

您提供的代码段显示,当您从粘贴板读取并更改文本存储时,您不会通过调用shouldChangeText(...)和didChangeText()来通知其他组件,这会导致文本之间的不一致存储和渲染。您应该能够通过包装如下代码来解决问题:

self.shouldChangeText(in:self.rangeForUserTextChange, replacementString: string)
self.textStorage?.replaceCharacters(in: self.rangeForUserTextChange, with: string)
self.didChangeText()