从粘贴板读取后 NSTextAttachment 内容属性为零

问题描述

我有一个自定义NSTextView 子类,它显示一个或多个表示令牌的 NSTextAttachment 对象(类似于 NSTokenField)。

问题是 contents 上的 NSTextAttachment 属性在从粘贴板读取 NSAttributedString 后始终为零,即使我看到此数据正在保存到粘贴板。>

  1. 创建文本附件并将其插入文本存储
let attachmentData = "\(key):\(value)".data(using: .utf8)
let attachment = NSTextAttachment(data: attachmentData,ofType: kUTTypeUTF8PlainText as String)
attachment.attachmentCell = CustomAttachmentCell(key: key,value: value)
...
textStorage.replaceCharacters(in: range,with: NSAttributedString(attachment: attachment))
  1. CustomAttachmentCell一个标准的 NSTextAttachmentCell 子类,只处理自定义绘图。它按预期在文本视图中绘制文本附件,并使用标准 CoreGraphics API 调用为附件的视觉表示绘制背景和文本。
class CustomAttachmentCell: NSTextAttachmentCell {
    
    let key: String
    let value: String

    override func draw(withFrame cellFrame: NSRect,in controlView: NSView?) {
        drawKey(withFrame: cellFrame,in: controlView)
        drawValue(withFrame: cellFrame,in: controlView)
    }

}
  1. 配置 NSTextViewDelegate 方法来处理将附件写入粘贴板
// If the prevIoUs method is not used,this method and the next allow the textview to take care of attachment dragging and pasting,with the delegate responsible only for writing the attachment to the pasteboard.
// In this method,the delegate should return an array of types that it can write to the pasteboard for the given attachment.
func textView(_ view: NSTextView,writablePasteboardTypesFor cell: NSTextAttachmentCellProtocol,at charIndex: Int) -> [NSPasteboard.PasteboardType] {
    return [(kUTTypeFlatRTFD as NSPasteboard.PasteboardType)]
}
    
// In this method,the delegate should attempt to write the given attachment to the pasteboard with the given type,and return success or failure.
func textView(_ view: NSTextView,write cell: NSTextAttachmentCellProtocol,at charIndex: Int,to pboard: NSPasteboard,type: NSPasteboard.PasteboardType) -> Bool {
     guard type == kUTTypeFlatRTFD as NSPasteboard.PasteboardType else { return false }
     guard let attachment = cell.attachment else { return false }
     return pboard.writeObjects([NSAttributedString(attachment: attachment)])
}
  1. 在文本视图中右键单击文本附件并从上下文菜单中选择“剪切”后,我可以使用 Clipboard Viewer.app 在粘贴板中看到 RTFD 数据:
rtfd............
...Attachment.........TXT.rtf....M...÷...........exampleKey:exampleValue....E.......
...Attachment....TXT.rtf..........Ñ`¶...........².Ñ`¶...............ï...{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0

\f0\fs24 \cf0 {{\NeXTGraphic Attachment \width640 \height640 \appleattachmentpadding0 \appleembedtype0 \appleaqc
}¬}\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
\cf0 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
\cf0 {{\NeXTGraphic Attachment \width640 \height640 \appleattachmentpadding0 \appleembedtype0 \appleaqc
}¬}}
  1. 现在,当我粘贴回文本视图并调用 textStorageWillProcessEditing() 时。我希望此时能够检索文本附件内容属性,但它始终为零。我是否遗漏了这条链中的某些关键部分?
override func textStorageWillProcessEditing(_ notification: Notification) {
     guard let attributedString = notification.object as? NSAttributedString else { return }
     attributedString.enumerateAttribute(.attachment,in: NSRange(location: 0,length: attributedString.length),options: [],using: { (value,range,stop) in
         if let attachment = value as? NSTextAttachment {
             // attachment.contents is nil here,I was expecting a Data object representing the UTF-8 string "exampleKey:exampleValue"
         }
     })
 }

或者,我尝试在我的 NSTextView 子类中覆盖一些与粘贴板相关的方法来做同样的事情(读/写 rftd 数据)。

  1. 覆盖 readablePasteboardTypes() 以重新排序,以便最丰富的数据(例如 com.apple.flat-rtfd / NeXT RTFD 粘贴板类型)排在数组的首位。
  2. 覆盖 preferredPasteboardType(from: restrictedToTypesFrom:) 以返回 (kUTTypeFlatRTFD as NSPasteboard.PasteboardType)
  3. 覆盖readSelection(from:type:)

当覆盖上述方法时,我会看到相同的行为:

  1. 从粘贴板上读取NSAttributedString
  2. 枚举属性字符串中包含的 NSTextAttachment 对象
  3. 枚举的 NSTextAttachment 对象 contents 属性始终设置为 nil 而不是 Data 表示写入 NSTextAttachment 内的粘贴板的 UTF-8 字符串“exampleKey:exampleValue” {1}} 位于 NSAttributedString 内。

这似乎是一个相当深奥的问题,因为我发现的所有示例代码搜索结果都使用 NSFileWrapperNSImage/UIImage支持他们的 {{1 }} 而不是 NSTextAttachment 初始值设定项。

谢谢!

解决方法

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

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...