Fast and Lean PDF Viewer for iPhone / iPad / iOS - tips and hints?

后端 未结 3 741
攒了一身酷
攒了一身酷 2020-11-22 06:47

There has been many Questions recently about drawing PDF\'s.

Yes, you can render PDF\'s very easily with a UIWebView but this cant give the performance

相关标签:
3条回答
  • 2020-11-22 07:18

    Since iOS 11, you can use the native framework called PDFKit for displaying and manipulating PDFs.

    After importing PDFKit, you should initialize a PDFView with a local or a remote URL and display it in your view.

    if let url = Bundle.main.url(forResource: "example", withExtension: "pdf") {
        let pdfView = PDFView(frame: view.frame)
        pdfView.document = PDFDocument(url: url)
        view.addSubview(pdfView)
    }
    

    Read more about PDFKit in the Apple Developer documentation.

    0 讨论(0)
  • 2020-11-22 07:29

    For a simple and effective PDF viewer, when you require only limited functionality, you can now (iOS 4.0+) use the QuickLook framework:

    First, you need to link against QuickLook.framework and #import <QuickLook/QuickLook.h>;

    Afterwards, in either viewDidLoad or any of the lazy initialization methods:

    QLPreviewController *previewController = [[QLPreviewController alloc] init];
    previewController.dataSource = self;
    previewController.delegate = self;
    previewController.currentPreviewItemIndex = indexPath.row;
    [self presentModalViewController:previewController animated:YES];
    [previewController release];
    
    0 讨论(0)
  • 2020-11-22 07:34

    I have build such kind of application using approximatively the same approach except :

    • I cache the generated image on the disk and always generate two to three images in advance in a separate thread.
    • I don't overlay with a UIImage but instead draw the image in the layer when zooming is 1. Those tiles will be released automatically when memory warnings are issued.

    Whenever the user start zooming, I acquire the CGPDFPage and render it using the appropriate CTM. The code in - (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context is like :

    CGAffineTransform currentCTM = CGContextGetCTM(context);    
    if (currentCTM.a == 1.0 && baseImage) {
        //Calculate ideal scale
        CGFloat scaleForWidth = baseImage.size.width/self.bounds.size.width;
        CGFloat scaleForHeight = baseImage.size.height/self.bounds.size.height; 
        CGFloat imageScaleFactor = MAX(scaleForWidth, scaleForHeight);
    
        CGSize imageSize = CGSizeMake(baseImage.size.width/imageScaleFactor, baseImage.size.height/imageScaleFactor);
        CGRect imageRect = CGRectMake((self.bounds.size.width-imageSize.width)/2, (self.bounds.size.height-imageSize.height)/2, imageSize.width, imageSize.height);
        CGContextDrawImage(context, imageRect, [baseImage CGImage]);
    } else {
        @synchronized(issue) { 
            CGPDFPageRef pdfPage = CGPDFDocumentGetPage(issue.pdfDoc, pageIndex+1);
            pdfToPageTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, layer.bounds, 0, true);
            CGContextConcatCTM(context, pdfToPageTransform);    
            CGContextDrawPDFPage(context, pdfPage);
        }
    }
    

    issue is the object containg the CGPDFDocumentRef. I synchronize the part where I access the pdfDoc property because I release it and recreate it when receiving memoryWarnings. It seems that the CGPDFDocumentRef object do some internal caching that I did not find how to get rid of.

    0 讨论(0)
提交回复
热议问题