图像插入后{N44extView未更新

时间:2016-05-26 10:01:45

标签: swift macos

我的应用程序(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倍。

任何人都可以就这为何起作用提出一些想法吗?

1 个答案:

答案 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。老实说,我不知道它是如何运作的。

干杯。 保罗。