iOS打印NSAttributed字符串,图像作为NSTextAttachement转换为PDF

iOS打印NSAttributed字符串,图像作为NSTextAttachement转换为PDF,ios,swift,nsattributedstring,uiprintpagerenderer,uiprintformatter,Ios,Swift,Nsattributedstring,Uiprintpagerenderer,Uiprintformatter,我正在尝试将UITextView的内容转换为PDF。UITextView使用包含文本和图像的NSAttributedString。 这些图像是NSTextAttachment的实例 我通过UIPrintPageRenderer传递了UIPrintFormatter,我从UITextView通过它的viewPrintFormatter()函数得到它,它对文本非常有效,但我看不到任何图像。看起来图像实际上占用了空间,因为我可以看到文本行之间的空白,但没有渲染图像 我怀疑它可能是格式化程序,但我不知道

我正在尝试将
UITextView
的内容转换为PDF。
UITextView
使用包含文本和图像的
NSAttributedString
。 这些图像是
NSTextAttachment
的实例

我通过
UIPrintPageRenderer
传递了
UIPrintFormatter
,我从
UITextView
通过它的
viewPrintFormatter()
函数得到它,它对文本非常有效,但我看不到任何图像。看起来图像实际上占用了空间,因为我可以看到文本行之间的空白,但没有渲染图像

我怀疑它可能是格式化程序,但我不知道如何解决它。 非常感谢您的帮助

我用于从
nsattributestring
创建PDF的代码如下:

public func createPDF(text: NSAttributedString, documentPath: URL, customPrintFormatter: UIPrintFormatter? = nil) {
    let printFormatter = customPrintFormatter == nil ? UISimpleTextPrintFormatter(attributedText: text) : customPrintFormatter!

    let renderer = UIPrintPageRenderer()
    renderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)

    // A4 size
    let pageSize = CGSize(width: 595.2, height: 841.8)

    // create some sensible margins
    let pageMargins = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72)

    // calculate the printable rect from the above two
    let printableRect = CGRect(x: pageMargins.left, y: pageMargins.top, width: pageSize.width - pageMargins.left - pageMargins.right, height: pageSize.height - pageMargins.top - pageMargins.bottom)

    // and here's the overall paper rectangle
    let paperRect = CGRect(x: 0, y: 0, width: pageSize.width, height: pageSize.height)

    renderer.setValue(NSValue(cgRect: paperRect), forKey: "paperRect")
    renderer.setValue(NSValue(cgRect: printableRect), forKey: "printableRect")

    let pdfData = NSMutableData()

    UIGraphicsBeginPDFContextToData(pdfData, paperRect, nil)
    renderer.prepare(forDrawingPages: NSMakeRange(0, renderer.numberOfPages))

    let bounds = UIGraphicsGetPDFContextBounds()

    for i in 0  ..< renderer.numberOfPages {
        UIGraphicsBeginPDFPage()

        renderer.drawPage(at: i, in: bounds)
    }

    UIGraphicsEndPDFContext()

    do {
        try pdfData.write(to: documentPath)
    } catch {
        print(error.localizedDescription)
    }
}

在public func createPDF(text:NSAttributedString,documentPath:URL)let printFormatter=ui impletextprintformatter(attributedText:text)中省略自定义打印机逻辑时会发生什么情况?(这似乎是您的逻辑中唯一与HackingWithWift文章不同的部分,因此可能是问题的原因。)此外,您是否可以发布创建传入的属性文本的逻辑?@SteveRobertson如果我只使用
UISimpleTextPrintFormatter
,没有什么区别。两者的产量相同。我在原始问题中添加了自定义
NSStorage
类的代码片段,该类创建了
NSTextAttachment
。没什么特别的,但是我可以在
UITextView
中看到使用该
NSStorage
对象的图像。当您像在public func createPDF(text:NSAttributedString,documentPath:URL)中那样省略自定义打印机逻辑时会发生什么?(这似乎是您的逻辑中唯一与HackingWithWift文章不同的部分,因此可能是问题的原因。)此外,您是否可以发布创建传入的属性文本的逻辑?@SteveRobertson如果我只使用
UISimpleTextPrintFormatter
,没有什么区别。两者的产量相同。我在原始问题中添加了自定义
NSStorage
类的代码片段,该类创建了
NSTextAttachment
。没什么特别的,但是我可以在
UITextView
中看到使用该
NSStorage
对象的图像。
        let attachment = NSTextAttachment()
        attachment.image = UIImage.init(named: "1.png")
        attachment.bounds = CGRect.init(x: 0, y: 0, width: 200, height: 100)
        let img = NSMutableAttributedString.init(attachment: attachment)

        let imgRange = NSRange.init(location: match.range(at: 0).location + match.range(at: 0).length, length: img.length)
        self.beginEditing()
        backingStore.insert(img, at: match.range(at: 0).location + match.range(at: 0).length)
        let r = NSMakeRange(match.range(at: 0).location + match.range(at: 0).length, img.length)
        self.edited([.editedCharacters, .editedAttributes], range: range, changeInLength: img.length)
        self.endEditing()