IOS development of the PDF document loading and browsing in 4 ways

Preface

In our development, some of the development of e-books like app will involve the loading and presentation of PDF documents. As the author of the project is just related to this piece, so the PDF will be used in several ways to make a summary of loading. For the students may be used as a reference.

text

We usually use the PDF document loaded in 4 ways:

  • UIWebView load local or network PDF documents
  • QLPreviewController loading PDF documents
  • CGContext painting with PDF documents, and combined with UIPageViewController display
  • Third party framework vfr/Reader loading PDF documents

The following in accordance with the above 4 methods in order to introduce the specific usage.

UIWebView load local or network PDF documents

UIWebView loading PDF document is relatively simple, almost the same as loading local documents and web documents.
browser is the upper and lower drive, support zoom, as well as the choice of copy, etc..
load local document:

UIWebView *myWebView = [[UIWebView / / initialize myWebView alloc] init]; myWebView.backgroundColor [UIColor = whiteColor]; NSURL = *filePath [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@ "myHome" ofType:@ "PDF"; "NSURLRequest * request = [NSURLRequest requestWithURL: filePath]; [myWebView loadRequest:request]; / / the display range for UIWebView bounds [myWebView setScalesPageToFit:YES] document;

Load network document:

UIWebView *myWebView = [[UIWebView / / initialize myWebView alloc] init]; myWebView.backgroundColor [UIColor = whiteColor]; NSURL = *filePath [NSURL URLWithString:@ "https://www.tutorialspoint.com/ios/ios_tutorial.pdf"]; NSURLRequest *request = [NSURLRequest requestWithURL: filePath]; [myWebView loadRequest:request]; / / the display range for UIWebView bounds [myWebView setScalesPageToFit:YES] document;
QLPreviewController loading PDF documents

In iOS 4 SDK after Apple launched the QLPreviewControllerAPI, the component allows the user to browse many different file types, such as XLS files, Word files, PDF files, but the user must use this API before importing the QuickLook.framework framework, using QLPreviewController two, you must implement this protocol proxy method QLPreviewControllerDataSource.
up and down sliding support for a single document browsing, left and right sliding support for switching between different documents, but also supports Apple’s own share printing, etc.. Two proxy methods for
QLPreviewControllerDataSource:

The number of load / * * * / PDF document - (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController * controller); / * * returns each document path corresponding to the index PDF documentation - (ID < QLPreviewItem> previewController:) (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index;

QLPreviewController loading PDF documents

//QLPreviewController initialization, QLPreviewController *QLPVC need to import the QuickLook.framework = [[QLPreviewController alloc] init]; QLPVC.dataSource = self; [self presentViewController:QLPVC animated:YES completion:nil]; #pragma mark QLPreviewControllerDataSource (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller{return 2;} - (id< QLPreviewItem> previewController:) (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index{NSArray *arr = @[FILE_PATH, FILE_PATH1]; return [NSURL fileURLWithPath:arr[index]];}
CGContext painting with PDF documents, and combined with UIPageViewController display

First of all, PDF single page document on the canvas UIView:

//CFURLRef pdfURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (), CFSTR ("test.pdf"), NULL, NULL); CFURLRef pdfURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (__bridge), (CFStringRef) self.fileName, NULL, NULL); / / create a CGPDFDocument object CGPDFDocumentRef pdfDocument = CGPDFDocumentCreateWithURL (pdfURL (CFURLRef)); / / get the current context of CGContextRef = *context (UIGraphicsGetCurrentContext); //Quartz and UIView coordinate system is not the same, adjust the coordinate system, the PDF based CGContextTranslateCTM (context, 0, self.bounds.size.height); CGContextScaleCTM (context, 1, -1.0); / / PDF = CGPDFDocumentGetPage page CGPDFPageRef document access to the specified page (pdfDocument, pageNO); / / create an affine transformation based on the PDF transform, page B OX mapping to the specified rectangle. CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform (page, kCGPDFCropBox, self.bounds, 0, true); CGContextConcatCTM (context, pdfTransform); / / PDF will be drawn to the context of CGContextDrawPDFPage (context, page);

Using UIPageViewController to display the paging PDF document

Initialize the PDFPageModel pdfPageModel = [[CGContextDrawPDFPageModel alloc] / / initWithPDFDocument:pdfDocument] / / UIPageViewControllerSpineLocationMin; *options = [NSDictionary single page display NSDictionary dictionaryWithObject: [NSNumber numberWithInteger: UIPageViewControllerSpineLocationMin] forKey: UIPageViewControllerOptionSpineLocationKey]; / / initialize UIPageViewController, UIPageViewControllerTransitionStylePageCurl flip effect, the level of UIPageViewControllerNavigationOrientationHorizontal = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl pageViewCtrl flip direction NavigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options]; / / PDF page of the bearing controller CGContextDrawPDFPageController *initialViewController = [pdfPageModel viewControllerAtIndex:1]; NSArray *viewControllers = [NSArray / arrayWithObject:initialViewController]; data source [pageViewCtrl setDataSource:pdfPageModel] settings UIPageViewController; //pageViewCtrl.doubleSided = YES; set up both positive and negative animated:NO [pageViewCtrl setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionReverse set pageViewCtrl controller / text Completion:^ (BOOL f) {}]; [self addChildViewController:pageViewCtrl]; [self.view addSubview:pageViewCtrl.view]; / / when we view our controller to the container (that is, the parent view controller, it calls the addChildViewController method with sub view controller, it has become a container view controller) to add (or remove) the child view controller, you must call this method to tell iOS, has been completed to add (or remove) sub controller operation. [pageViewCtrl didMoveToParentViewController:self]; //CGContextDrawPDFPageModel.m pdfDocument long / / get the total number of pageSum = CGPDFDocumentGetNumberOfPages (pdfDocument); #pragma mark pageViewController to return the current page Previous page proxy method (doubleSide attributes such as style, back to the front page display and the same instead of the default white, need to set the pageController to YES, while the two agent method in the following settings) - BackViewController (UIViewController *) pageViewController: (* UIPageViewController) pageViewController viewControllerBeforeViewController: (UIViewController * viewController) {NSUInteger index = [self indexOfViewController: (CGContextDrawPDFPageController * viewController]); if ((index = = 1) || (index = = NSNotFo Und)) {return} nil; index--; return [self viewControllerAtIndex:index]; #pragma mark pageViewController} proxy method return current page page - (UIViewController *) pageViewController: (* UIPageViewController) pageViewController viewControllerAfterViewController: (UIViewController * viewController) {NSUInteger index = [self indexOfViewController: (CGContextDrawPDFPageController *) viewController]; if (index = = NSNotFound) {return nil index++;}; / / get the PDF document pages long pageSum = CGPDFDocumentGetNumberOfPages (pdfDocument); if (index = > pageSum+1) {return} nil; return [self viewControllerAtIndex:index];}

Perhaps we will notice in peacetime, some e-book reader in the process of turning the page will have the day mode and night mode, and UIPageViewController default page effect is as follows:

IOS development of the PDF document loading and browsing in 4 ways
flip default effect.Png

If the night mode is also the default effect will be very embarrassing figure:

IOS development of the PDF document loading and browsing in 4 ways
night mode.Jpeg

In order to solve this problem:
needs to be doubleSided’s UIPageViewController property to YES, and then back to the current view this page screenshot of each page in the back of the effect and the corresponding mode corresponding to the.
major changes in two places:
1: a new controller is set on the back of the view, at the same time to load a UIImageView on the controller is set to the current page picture books a screenshot of the implementation are as follows:

- (void) updateWithViewController: (UIViewController * viewController) {self.backgroundImage [self = captureView:viewController.view];} - (UIImage *) captureView: (UIView * view) {CGRect rect = view.bounds; UIGraphicsBeginImageContextWithOptions (rect.size, YES, 0.0F); CGContextRef context = UIGraphicsGetCurrentContext (CGAffineTransform); transform = CGAffineTransformMake (-1.0, 0, 0, 1, rect.size.width, 0); CGContextConcatCTM (context, transform); [view.layer renderInContext:context]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext (UIGraphicsEndImageContext); (return); image;}

Second: in the UIPageViewController dataSource proxy method, set the back page for the screenshot controller.

#pragma mark if you want to display on the back page style and the same positive, rather than the default white, need to set the doubleSide property of pageController YES, while two proxy methods are described in the following BackViewController - (UIViewController *) pageViewController: (UIPageViewController *) pageViewController viewControllerBeforeViewController: (UIViewController * viewController) {if ([viewController isKindOfClass:[CGContextDrawPDFPageController class]]) {self.currentViewController = viewController; BackViewController = *backViewController [[BackViewController alloc] init]; [backViewController updateWithViewController:viewController]; return backViewController;} //self.currentViewController is saved after a CG ContextDrawPDFPageController, if viewController is actually used to refer to the backViewController, and it does not have indexOfViewController: other methods will collapse. NSUInteger index = [self indexOfViewController: (CGContextDrawPDFPageController * self.currentViewController]); if ((index = = 1) || (index = = NSNotFound) {return nil}); index-- return; [self viewControllerAtIndex:index];} - (UIViewController *) pageViewController: (* UIPageViewController) pageViewController viewControllerAfterViewController: (UIViewController * viewController) {if ([viewController isKindOfClass:[CGContextDrawPDFPageController class]]) {self.currentViewController = viewController; BackViewController *backViewController = [[BackViewController alloc] init]; [backViewController updateWithViewController:viewController]; return backViewController //self.current;} ViewController is holding a CGContextDrawPDFPageController before, if the direct use of viewController refers to the backViewController, but it does not have a indexOfViewController method: the program will collapse. NSUInteger index = [self indexOfViewController: (CGContextDrawPDFPageController *) self.currentViewController]; if (index = = NSNotFound) {return nil}; index++; / / get the PDF document pages long pageSum = CGPDFDocumentGetNumberOfPages (pdfDocument); if (index = > pageSum+1) {return} nil; return [self viewControllerAtIndex:index];}
Third party framework vfr/Reader loading PDF documents

Using third party framework vfr/Reader loading PDF documents is very easy to use, integrated print, share, send e-mail, preview and other functions, directly on the code as follows:

//Reader initialization loading local PDF file = [[ReaderDocument ReaderDocument *doc alloc] initWithFilePath:FILE_PATH password:nil]; ReaderViewController *rederVC = [[ReaderViewController alloc] initWithReaderDocument:doc]; rederVC.delegate = self; rederVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; rederVC.modalPresentationStyle = UIModalPresentationOverFullScreen; [self presentViewController:rederVC animated:YES completion:nil] #pragma mark ReaderViewControllerDelegate PDF; because the reader may be push, may also be present, in order to better effect, this agent the method can achieve a good exit - (void) dismissReaderViewController: (ReaderVi EwController *) viewController{[self completion:nil] dismissViewControllerAnimated:YES;}

Source has been uploaded to fenglinyunshi-git, welcome to download, and made valuable comments.

epilogue

Loading PDF file may have more ways to achieve, welcome to add, if there is not exactly the right place to correct, thank you.

How can it be so clear, as has the springhead.