1

I'm trying to draw a PDFPage onto the context of a UIView subclass:

class PDFPageView: UIView {

    private let page: PDFPage

    init(frame: CGRect, page: PDFPage) {
        self.page = page
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }

    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }

        // This scales the page correctly (ignoring aspect ratios for now, though)
        let bounds = page.bounds(for: .mediaBox)
        context.scaleBy(x: rect.width / bounds.width, y: rect.height / bounds.height)

        // This has no effect when I use it (?)
        // page.transform(context, for: .mediaBox)


        page.draw(with: .mediaBox, to: context)
    }
}

It is drawing something, but it is mirrored (vertically) and I don't know how to correct this. I thought page.transform(context, for: .mediaBox) should do everything so that the context renders the page correctly. But it does nothing, strangely.

I tried to manually set the scale. It's working, but only for positive values. If I try to set a negative x-scale or y-scale (to compensate for the mirroring) I only get a black screen on my device.

I'm not sure what I should do. Also, it is only working for some pdf. I wanted to show you a screenshot so I created a small pdf file (the ones I use for testing are copyrighted, I think) and loaded it into the app. But I only get a black screen her as well.

I'd really appreciate any help with this.

Thank you


EDIT: Okay, I got it kind of working. After scaling the y-axis by a negative value, I need to translate the context using context.translateBy(x: 0, y: rect.height). Then it's rendered correctly.

But still, why is page.transform(context, for: .mediaBox) not doing this? And is vertically flipping the context valid for every pdf page?

SwiftedMind
  • 3,701
  • 3
  • 29
  • 63
  • what is the purpose of use custom UIview instead of the **PdfView** class? – Razib Mollick Apr 06 '18 at 13:04
  • As I understand it, `PDFView` is for files, not for a single page. I need a view for a single pdf page. I'm building a custom pdf viewer because `PDFKit` with its classes and methods behaves pretty strange (see: https://stackoverflow.com/questions/49335737/pdfkit-pdfview-using-pageviewcontroller-page-rendering-slow-when-swiping-to/49685678#49685678) – SwiftedMind Apr 06 '18 at 13:07
  • Ahh, you are still struggling. I did comment on that post too. – Razib Mollick Apr 06 '18 at 13:26
  • Oh, yeah I see :D. Yes, I'm still struggling with this :D. As there seems to be no magic attribute to set or anything, I decided to build everything on my own, using a collectionView whose cells contain individual pages of a pdf. That way I can prerender cells before they become visible and avoid the problem of slow loading (hopefully) – SwiftedMind Apr 06 '18 at 13:28
  • 2
    FYI: The origin of the PDF coordinate system (0, 0) represents the bottom-left corner of the PDF page. It means, In the PDF file format, increasing X values specify the rightward direction and increasing Y values specify the upward direction. so, you have to flip the coordinate system. For example of code: context.translateBy(x: 0.0, y: bounds.size.height) context.scaleBy(x:0.7, y: -1.0) – Razib Mollick Apr 06 '18 at 13:30
  • Yeah, that's basically working (see edit). Though, I thought `page.transform(context, for: .mediaBox)` should take care of this. For now, it's working. But I don't know if it will work for every pdf – SwiftedMind Apr 06 '18 at 13:31
  • 1
    For future internet searchers, here is working Swift code to render a PDF page in a UIView. It has a Cartography dependency but it's easy to rewrite without it. https://gist.github.com/stevelandeyasana/b50d507a6ba822372fad224ac9639b7d – Steve Landey Feb 10 '20 at 23:18

0 Answers0