代码之家  ›  专栏  ›  技术社区  ›  Joseph Williamson

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

  •  5
  • Joseph Williamson  · 技术社区  · 7 年前

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

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

    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行原来的位置删除文本,因为第1行下添加了一行,所以现在包含第4行。

    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.
    */
    

    1 回复  |  直到 7 年前
        1
  •  6
  •   Joseph Williamson    7 年前

    在联系苹果寻求支持后,我得到了答案,这是报价。

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

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