我的应用程序(swift,OSX,Xcode,所有内容的最新版本)都有一个NSTextView,我允许用户输入。 NSTextView启用了RichText,图形和NSInspectorBar。
我将NSTextView的内容加载/保存为webarchive格式(发牢骚 - 但我需要一种包含图像的可移植格式)。
到目前为止一切顺利。一切都有效...除了一个小细节。当我将图像插入TextView时,它不会显示。但它就在那里,因为如果我保存并加载......它会出现。
这里是我如何将图像插入NSTextView(我从NSOpenPanel获取图像的路径:
guard let theImage = NSImage(contentsOfURL: openPanel.URL!) else {
showErrorMessage("Unable to load image")
return
}
// self.textEditor is the NSTextView
guard let store = self.textEditor.textStorage else { abort() }
let attachment = NSTextAttachment()
attachment.image = theImage
let attrString = NSAttributedString(attachment: attachment)
let range = self.textEditor.selectedRange()
store.replaceCharactersInRange(range, withAttributedString: attrString)
我认为它相当直接:加载图像,添加到一个attributesString,用referencedString替换所选字符。
然而没有出现。对NSTextView没有任何改变。如果我将NSTextStorage内容保存为webarchive:
guard let store = textEditor.textStorage else { abort() }
let attr: [String: AnyObject] = [NSDocumentTypeDocumentAttribute: NSWebArchiveTextDocumentType]
let data = try store.dataFromRange(NSMakeRange(0, store.length), documentAttributes: attire)
//... save 'data' to DB ...
然后重新加载它们:
//... load 'data' from the DB ...
guard let store = textEditor.textStorage else { abort() }
let str = try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute:NSWebArchiveTextDocumentType], documentAttributes: nil)
store.setAttributedString(str)
......图像恰好出现在正确的位置。
我很困惑这个。有没有人对我缺少的东西有任何想法?
BTW - 我尝试使用以下方法强制刷新:
let frame = self.textEditor.frame
self.textEditor.setNeedsDisplayInRect(frame)
那不起作用。
对您提供的任何建议提出建议。 干杯。 保罗
编辑:附录......我一直在搞乱NSTextAttachmentCells,希望它们可以正常工作。它们以完全不同的方式失败。
如果我只是将上面的图像插入代码替换为:
let cell = NSTextAttachmentCell(imageCell: theImage)
let txtAtt = NSTextAttachment()
txtAtt.attachmentCell = cell
let str = NSAttributedString(attachment: txtAtt)
let range = self.textEditor.selectedRange()
store.replaceCharactersInRange(range, withAttributedString: str)
...然后图像会在插入后立即显示,并且位于正确的位置。但他们没有得救!也就是说,当我进行保存和重新加载时(根据上面的代码),它们不会包含在webarchive中。
编辑^ 2: 因此,上面的明显结论是将一个图像附加到TextAttachment 和附加到NSTextAttachmentCell的图像,该图像也附加到TextAttachment。嗯......这不起作用。但是这是什么工作:
let cell = NSTextAttachmentCell(imageCell: theImage)
let txtAtt = NSTextAttachment(data: theImage.TIFFRepresentation, ofType: kUTTypeTIFF as String)
txtAtt.attachmentCell = cell
//txtAtt.image = theImage
let str = NSAttributedString(attachment: txtAtt)
let rng = self.textEditor.selectedRange()
store.replaceCharactersInRange(rng, withAttributedString: str)
那就是......我创建一个TextAttachment,传递图像的TIFF表示数据。我还创建了AttachmentCell。这现在有效 - 插入是可见的并且可以保存。
唯一的缺点是TIFF很大 - 图像扩展到内存大小的3倍。
任何人都可以就这为何起作用提出一些想法吗?
答案 0 :(得分:3)
好的 - 这是解决方案。
NSTextAttachmentCell代表
...用于绘制文本附件图标并在其图标apple docs上处理鼠标事件的对象的界面。
因此您需要使用图像创建其中一个。
NSTextAttachment
...包含NSData对象或NSFileWrapper对象,后者又保存附加文件的内容apple docs
所以你需要两个 - 一个用于显示和交互,一个用于保存(即实际数据)。保存TIFF(太大)时遇到的问题可以通过创建JPG或PNG表示来克服,这可以很好地用于NSData对象。我通过扩展NSImage做到了这一点:
extension NSImage {
var imagePNGRepresentation: NSData {
return NSBitmapImageRep(data: TIFFRepresentation!)!.representationUsingType(.NSPNGFileType, properties: [:])!
}
var imageJPGRepresentation: NSData {
return NSBitmapImageRep(data: TIFFRepresentation!)!.representationUsingType(.NSJPEGFileType, properties: [:])!
}
}
(感谢here的评论者关于如何做到这一点)。
所以这里的代码实际上可以将图像插入NSTextView(请滚筒)......
guard let theImage = NSImage(contentsOfURL: openPanel.URL!) else {
showErrorMessage("Unable to load image")
return
}
guard let store = self.textEditor.textStorage else { abort() }
let cell = NSTextAttachmentCell(imageCell: theImage)
let txtAtt = NSTextAttachment(data: theImage.imageJPGRepresentation, ofType: kUTTypeJPEG as String)
txtAtt.attachmentCell = cell
let str = NSAttributedString(attachment: txtAtt)
let range = self.textEditor.selectedRange()
store.replaceCharactersInRange(range, withAttributedString: str)
当我将其保存为webarchive时,我可以看到JPG对象与HTML一起保存。
扩展此...您可以插入任何数据类型(例如docs)并在Cell中使用图标表示。凉。
奇怪的是,描述此内容的大多数网页都不包含Cell。老实说,我不知道它是如何运作的。
干杯。 保罗。