iOS How To Open and View PDF Files

Source

(c) 2012 kevin languedoc (klanguedoc)

There are different ways to open and view a PDF file in an iOS application. First you use the UIWebView, which I will demonstrate in this tutorial, you can also use the UIDocumentInteractionController class to open and view PDF files using the presentPreviewAnimated and dismissPreviewAnimated methods or the CGPDFDocumentRefclass in the Core Foundation framework. Each offers an easy way to open and view PDF documents

As previously cited, I will use the UIWebView to load a PDF document that is located in the Documents directory. This tutorial is an extension of a previous tutorial that demonstrated how to create PDF using the UIKit: iOS Create PDF using UIKit. In this tutorial I will add a View Controller and an UIPickerView to load PDFs files in the Documents and display the PDF in another View Controller.

Application Tutorial Steps

You can either use the source code from the previous tutorial that you can download from this site, or build an application from scratch, either way you will start with a blank UIViewController.

  1. Add a UIViewController to the existing project or create a Single View Controller application.
  2. Add an UIPickerView to the UIViewController.
  3. Add an UIButton to the UIViewController beneath the UIPickerView.
  4. Change the button’s label to the following by clicking on it: “Load PDF”.
  5. If this a new UIViewController in an existing project, add a new file as a subclass of the UIViewController, taking care to not create a xib file. Name it listPDFVC.
  6. Again if this is a new UIViewController, add the newly created UIViewController subclass to the custom class field in the Identity inspector, otherwise you can skip this step.
  7. Drag a connection from the UIPickerView to the UIViewController proxy and select the delegate from the outlets. Repeat the same process and select the data source. This will bind the delegate and data source protocols that we will define in the header file next.
  8. Open the header file and drag a connection from the UIPickerView to the header file between the @interface and @end directives. Releasing the mouse a popover will appear allowing you to name the IBOutlet: listPDF.
  9. Before getting to the header and implementation files, add another UIViewController to the Storyboard.
  10. Next add a UIWebView to this new UIViewController.
  11. Now drag a connection from the UIButton in the first UIViewController to the new UIViewController making sure not to release the connection string on the UIWebView. Rather release it near the top of the UIViewController. This will be the segue.
  12. With the segue selected, switch to the attributes inspector and give the segue an identifier (name) like pdfSegue.
  13. Next create a new custom class as a subclass of the UIViewController. Name it displayPDFVC.
  14. Add this new UIViewController subclass to the UIViewController through the custom class field in the Identity inspector.
  15. Now open the header file by selecting the Editor assistant as before and drag a connection from the UIWebView to the header file. Name this IBOutlet: displayPDF.


With the Storyboard complete, we can add the logic to make it all work.

ListPDFVC Logic

  • Open the ListPDFVC header and add an import statement for the ViewPDFVC.h class.
  • Next add the UIPickerViewDataSource and UIPickerViewDelegate protocols as in the source code below.
  • Add a NSMutableArray property. Call it: pdfList.
  • Then add a NSString property for the selected file name in the UIPickerView. Name it: pickerSelectedFile.
  • Finally add a method to populate the pdfList property. Name this method loadPDFList as in the source code.

ListPDFVC.h

//
//  ListPDFVC.h
//  PDF Creator
//
//  Created by Kevin Languedoc on 11/23/12.
//  Copyright (c) 2012 Kevin Languedoc. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ViewPDFVC.h"

@interface ListPDFVC : UIViewController<UIPickerViewDataSource,UIPickerViewDelegate>
@property (strong, nonatomic) IBOutlet UIPickerView *listPDF;

@property(strong,nonatomic) NSMutableArray * pdfList;
@property(strong,nonatomic) NSString *pickerSelectedFile;

-(void)loadPDFList;
@end
  • Finally open the implementation file and synthesize the properties using the @synthesize directive.
  • Add the loadPDFList method as in the source code.
  • Add a NSFileManager variable and set it the defaultManager which is the root directory.
  • Add a variable for the the path of the Documents directory using the NSSearchPathForDirectoriesInDomains and NSDocumentsDirectory which will add one element to the docDirArr NSArray
  • Assign the path of the Documents directory to the docDir NSString which will used to get the contents of the directory as a NSArray and assign the values to the dirContents NSArray.
  • Although not necessary since the documents directory only contains pdf file, I add a filter using the NSPredicate class to filter on pdf files only
  • Finally add the filtered array to the __pdfList NSMutableArray which will serve as the data source for the UIPickerView to complete the loadPDFList method.
  • Add the viewDidAppear of the UIViewController. In it call the loadPDFList as in the source code. This method is called every time after the first time.
  • Also add the listPDF reloadAllComponents method to refresh the UIPickerView when new files are added to the NSMutableArray.
  • In the ViewDidLoad method call the loadPDFList method as previously cited.
  • Add the required pickerView:numberOfRowsInComponent method returning the listPdf count to define the number of rows that the UIPickerView will contain.
  • The required numberOfComponentsInPickerView method defines the number of columns to display. In this example I set the return value to 1.
  • The required pickerView:titleForRow:forComponent method defines the value to display in the UIPickerView. Fro this I set the filenames as the value to display.
  • The pickerView:didSelectRow method assigns the selected value in the UIPickerView to the selectedPDFFile variable which we will pass tot he next UIViewController.
  • The final method to implement is the prepareForSegue method that works in conjunction with the segue. Since I only have one segue I don't check to see which segue is called but for multiple segues this is important.
  • Create a instance of the viewPDFVC class and assign it to the destinationViewController to set the target ViewController.
  • Finally assign the value of the selectedPDFFile variable to the selectedFile variable of the viewPDFVC. This will trigger the viewPDFVC to be pushed onto the stack.

ListPDFVC.m

//
//  ListPDFVC.m
//  PDF Creator
//
//  Created by Kevin Languedoc on 11/23/12.
//  Copyright (c) 2012 Kevin Languedoc. All rights reserved.
//

#import "ListPDFVC.h"

@interface ListPDFVC ()

@end

@implementation ListPDFVC
@synthesize listPDF;
@synthesize pickerSelectedFile;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view.
    [self loadPDFList];
}
-(void)viewDidAppear:(BOOL)animated{
     [self loadPDFList];
    [listPDF reloadAllComponents];
}

- (void)viewDidUnload
{
  
    [self loadPDFList];
    [self setListPDF:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    ViewPDFVC * viewPDF = [segue destinationViewController];
    viewPDF.selectedFile = pickerSelectedFile;
}

-(void)loadPDFList{
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    NSArray *docDirArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [docDirArr objectAtIndex:0];
    NSArray *dirContents = [fileMgr contentsOfDirectoryAtPath:docDir error:nil];
    NSPredicate *extFilter = [NSPredicate predicateWithFormat:@"self ENDSWITH '.pdf'"];
    _pdfList = [[NSMutableArray alloc] initWithArray:[dirContents filteredArrayUsingPredicate:extFilter]];
    
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    
    return [_pdfList count];
}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row
            forComponent:(NSInteger)component
{
    
    
    return [_pdfList objectAtIndex:row];
    
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    
    
    
    pickerSelectedFile = [_pdfList objectAtIndex:row];
    
    
    
}


@end

ViewPDFVC

  • In the header add a class directory to the current class as @class ViewPDFVC
  • Also add a NSString variable called, selectedFile which will contain the file whose contents will be displayed in the UIWebView.
  • In the implementation, synthesize the selectedFile variable
  • Also in the implementation file, the main method that will display the PDF contents will be the viewDidAppear which will be called when the view controller is loaded.
  • In this method, we get a handle on the Documents directory as before
  • Then assign the path of the PDF file to the pdfPath NSString variable and then passing this value to the NSURL variable pdfURL which will be used to load the file and its contents.
  • Next create a NSUrlRequest variable called pdfReq and initialize the variable using theinitWithURL method with the pdfUrl value.
  • Finally call the pdfViewer UIWebView and call the loadRequest method and passing thepdfReq variable's value to be displayed in the UIWebView

ViewPDFVC.h

//
//  ViewPDFVC.h
//  PDF Creator
//
//  Created by Kevin Languedoc on 11/25/12.
//  Copyright (c) 2012 Kevin Languedoc. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewPDFVC;
@interface ViewPDFVC : UIViewController
@property (strong, nonatomic) IBOutlet UIWebView *pdfViewer;

@property (strong, nonatomic) NSString *selectedFile;
@end

ViewPDFVC.m

//
//  ViewPDFVC.m
//  PDF Creator
//
//  Created by Kevin Languedoc on 11/25/12.
//  Copyright (c) 2012 Kevin Languedoc. All rights reserved.
//

#import "ViewPDFVC.h"

@interface ViewPDFVC ()

@end

@implementation ViewPDFVC

@synthesize pdfViewer, selectedFile;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view.
}

-(void)viewDidAppear:(BOOL)animated{
    NSArray * docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    
    //Define new path for database in the documents directory because data cannot be written in the resource folder.
    NSString * pdfPath = [[docPath objectAtIndex:0] stringByAppendingPathComponent:selectedFile];
    NSURL *pdfURL = [[NSURL alloc]initFileURLWithPath:pdfPath];
    NSURLRequest *pdfReq = [[NSURLRequest alloc] initWithURL:pdfURL];
    [pdfViewer loadRequest:pdfReq];
}

- (void)viewDidUnload
{
    [self setPdfViewer:nil];
  
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

More by this Author


Comments 2 comments

tillsontitan profile image

tillsontitan 4 years ago from New York

I'm afraid this is out of my league Klanguedoc...I use Adobe Reader and skip all the technical stuff. I voted this up because it is amazing!


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Hey thanks tillsontitan LOL. It does start to make sense the more you learn and use it.

    Sign in or sign up and post using a HubPages Network account.

    0 of 8192 characters used
    Post Comment

    No HTML is allowed in comments, but URLs will be hyperlinked. Comments are not for promoting your articles or other sites.


    Click to Rate This Article
    working