2

我目前正在开发一个应用程序,我想在 UICollectionView 之上实现一个 PDF 阅读器。

我在每个呈现相应 PDF 页面的单元格上使用自定义 UIView:

weak var page: CGPDFPage! {

    didSet { setNeedsDisplay() }

}

override func draw(_ rect: CGRect) {

    if page == nil {
        print("page is nil")
        return }

    let context = UIGraphicsGetCurrentContext()

    context?.clear(bounds)

    context?.setFillColor(red: 1, green: 1, blue: 1, alpha: 1)
    context?.fill(bounds)

    context?.translateBy(x: 0.0, y: bounds.size.height);
    context?.scaleBy(x: 1.0, y: -1.0);

    var cropBox = page.getBoxRect(.cropBox)
    cropBox = CGRect(x: cropBox.origin.x, y: cropBox.origin.y, width: ceil(cropBox.width), height: ceil(cropBox.height))

    let scaleFactor = min(bounds.size.width/cropBox.size.width, bounds.size.height/cropBox.size.height)
    let scale = CGAffineTransform(scaleX: scaleFactor, y: scaleFactor)
    let scaledInnerRect = cropBox.applying(scale)
    let translate = CGAffineTransform(translationX: ((bounds.size.width - scaledInnerRect.size.width) / 2) - scaledInnerRect.origin.x, y: ((bounds.size.height - scaledInnerRect.size.height) / 2) - scaledInnerRect.origin.y)
    let concat = translate.scaledBy(x: scaleFactor, y: scaleFactor)

    context?.concatenate(concat)

    let clipRect = cropBox
    context?.addRect(clipRect)
    context?.clip()

    context?.drawPDFPage(page)

    UIGraphicsEndPDFContext()

}

到目前为止,一切都很好。它在单元格上呈现页面,但会导致内存问题。

在此处输入图像描述

不知何故,上下文保持对集合视图单元格上呈现的所有页面的引用,并且它们没有被释放。CGPDFPageRelease 不再可用。:(

另一方面,如果这个 uiview 子类在滚动视图中放大,我如何重绘 pdf 以保证质量不下降?

任何帮助将不胜感激。谢谢!

4

3 回答 3

6

我有相同的代码和相同的问题,但是一旦我将其更改为这个新的解决方案,它就对我有所帮助。现在我在渲染 PDF 时没有任何内存问题。

autoreleasepool非常重要,因为它可以帮助您释放呈现的页面。这是我的代码。

迅速

class PDFPageRenderView: UIView {

    func render(page: CGPDFPage) {
        for subview in subviews { subview.removeFromSuperview() }
        let imageView = UIImageView(frame: bounds)
        imageView.contentMode = .scaleAspectFit
        imageView.clipsToBounds = true
        imageView.backgroundColor = UIColor.white
        autoreleasepool {
            let pageRect = page.getBoxRect(.mediaBox)
            let renderer = UIGraphicsImageRenderer(size: pageRect.size)
            let data =  renderer.jpegData(withCompressionQuality: kImageCompression, actions: { cnv in
                UIColor.white.set()
                cnv.fill(pageRect)
                cnv.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
                cnv.cgContext.scaleBy(x: 1.0, y: -1.0)
                cnv.cgContext.drawPDFPage(page)
            })
            imageView.image = UIImage(data: data)
        }
        addSubview(imageView)
    }
}
于 2018-07-12T21:22:33.153 回答
0

我们看到了同样的泄漏,它似乎只影响 iOS 10。这似乎是一个常见问题:https ://forums.developer.apple.com/message/174710#174710 我们还在 iOS 10.2 中对其进行了测试,但不能再找漏洞。你有没有试过看看这对你有用吗?

于 2016-12-01T12:13:17.240 回答
0

使用CATiledLayer解决页面缩放的渲染问题。

创建CATiledLayer的子类并在视图子类中覆盖以下给定方法

override class var layerClass: AnyClass {
        get {
            return YourCATiledLayerSubclass.self
        }
    }
于 2017-04-04T14:07:51.590 回答