NSTextView drag text with custom attributes

Viewed 606

I am having an issue regarding my NSTextView subclass. My view contains attributed strings with custom attributes, therefore I had to implement the following pasteboard methods to ensure that my custom attributes get copied on to the pasteboard.

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

In readSelection, I manually read the string on the pasteboard, and write it into the NSTextView's textStorage at rangeForUserTextChange.

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)

}

Now the problem is, when I select and drag texts up say from line 5 to under line 1, the text is inserted under line 1 correctly, however the system then attempts to remove text from where line 5 used to be, which now contains line 4 because an extra line has been added below line 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.
*/

As you can see, the system is removing the line after the length has been altered. I couldn't find any delegate method for intercepting when the drag and drop method removes text in the textStorage that was dragged from the textview.

1 Answers
Related