PDF Reader Core for iOS

Last update: Jun 17, 2022

PDF Reader Core for iOS


This project is no longer supported or maintained. It is only here for historical reasons. Please see the UXReader PDF Framework for iOS project for a possible replacement.


Introduction

I've crafted this open source PDF reader code for fellow iOS developers struggling with wrangling PDF files onto iOS device screens.

The code is universal and does not require any XIBs (as all UI elements are code generated, allowing for greatest flexibility). It runs on iPad, iPhone and iPod touch with iOS 6.0 and up. Also supported are the Retina displays in all new devices and is ready to be fully internationalized. The idea was to provide a complete project template that you could start building from, or, just pull the required files into an existing project to enable PDF reading/viewing in your app(s).

iPad Page

iPad Thumbs

iPod Page

iPod Thumbs

After launching the sample app, tap on the left hand side of the screen to go back a page. Tap on the right hand side to go to the next page. You can also swipe left and right to change pages. Tap on the screen to fade in the toolbar and page slider. Double-tap with one finger (or pinch out) to zoom in. Double tap with two fingers (or pinch in) to zoom out.

This implementation has been tested with large PDF files (over 250MB in size and over 2800 pages in length) and with PDF files of all flavors (from text only documents to graphics heavy magazines). It also works rather well on older devices (such as the iPod touch 4th generation and iPhone 3GS) and takes advantage of the dual-core processor (via CATiledLayer and multi-threading) in new devices.

To see an example open source PDF Viewer App that uses this code as its base, have a look at this project repository on GitHub: https://github.com/vfr/Viewer

Features

Multithreaded: The UI is always quite smooth and responsive.

Supports:

  • iBooks-like document navigation.
  • Device rotation and all orientations.
  • Encrypted (password protected) PDFs.
  • PDF links (URI and go to page).
  • PDFs with rotated pages.

Notes

Version 2.x of the PDF reader code was originally developed and tested under Xcode 3.2.6, LLVM 1.7 and iOS 4 with current development and testing under Xcode 7.2, LLVM 7.0 and iOS 9.2. Please note that as of v2.6, the code was refactored to use ARC.

The overall PDF reader functionality is encapsulated in the ReaderViewController class. To present a document with this class, you first need to create a ReaderDocument object with the file path to the PDF document and then initialize a new ReaderViewController with this ReaderDocument object. The ReaderViewController class uses a ReaderDocument object to store information about the document and to keep track of document properties (thumb cache directory path, bookmarks and the current page number for example).

An initialized ReaderViewController can then be presented modally, pushed onto a UINavigationController stack, placed in a UITabBarController tab, or be used as a root view controller. Please note that since ReaderViewController implements its own toolbar, you need to hide the UINavigationController navigation bar before pushing it and then show the navigation bar after popping it. The ReaderDemoController class shows how this is done with a bundled PDF file.

Required Files

The following files are required to incorporate the PDF reader into one of your projects:

CGPDFDocument.h, CGPDFDocument.m
ReaderDocument.h, ReaderDocument.m
ReaderConstants.h, ReaderConstants.m
ReaderViewController.h, ReaderViewController.m
ReaderMainToolbar.h, ReaderMainToolbar.m
ReaderMainPagebar.h, ReaderMainPagebar.m
ReaderContentView.h, ReaderContentView.m
ReaderContentPage.h, ReaderContentPage.m
ReaderContentTile.h, ReaderContentTile.m
ReaderThumbCache.h, ReaderThumbCache.m
ReaderThumbRequest.h, ReaderThumbRequest.m
ReaderThumbQueue.h, ReaderThumbQueue.m
ReaderThumbFetch.h, ReaderThumbFetch.m
ReaderThumbRender.h, ReaderThumbRender.m
ReaderThumbView.h, ReaderThumbView.m
ReaderThumbsView.h, ReaderThumbsView.m
ThumbsViewController.h, ThumbsViewController.m
ThumbsMainToolbar.h, ThumbsMainToolbar.m
UIXToolbarView.h, UIXToolbarView.m

Reader-Button-H.png, [email protected], [email protected]
Reader-Button-N.png, [email protected], [email protected]
Reader-Email.png, [email protected], [email protected]
Reader-Export.png, [email protected], [email protected]
Reader-Mark-N.png, [email protected], [email protected]
Reader-Mark-Y.png, [email protected], [email protected]
Reader-Print.png, [email protected], [email protected]
Reader-Thumbs.png, [email protected], [email protected]

Localizable.strings (UTF-16 encoding)

Required iOS Frameworks

To incorporate the PDF reader code into one of your projects, all of the following iOS frameworks are required:

UIKit, Foundation, CoreGraphics, QuartzCore, ImageIO, MessageUI

Compile Time Options

In ReaderConstants.h the following #define options are available:

READER_FLAT_UI - If TRUE, follows the Fuglyosity of Flat Fad (flattens the UI).

READER_SHOW_SHADOWS - If TRUE, a shadow is shown around each page and page thumbnail.

READER_ENABLE_THUMBS - If TRUE, a thumbs button is added to the main toolbar enabling page thumbnail document navigation.

READER_DISABLE_RETINA - If TRUE, sets the CATiledLayer contentScale to 1.0f. This effectively disables retina support and results in non-retina device rendering speeds on retina display devices at the loss of retina display quality.

READER_ENABLE_PREVIEW - If TRUE, a medium resolution page thumbnail is displayed before the CATiledLayer starts to render the PDF page.

READER_DISABLE_IDLE - If TRUE, the iOS idle timer is disabled while viewing a document (beware of battery drain).

READER_STANDALONE - If FALSE, a "Done" button is added to the toolbar and the -dismissReaderViewController: delegate method is messaged when it is tapped.

READER_BOOKMARKS - If TRUE, enables page bookmark support.

ReaderDocument Archiving

To change where the property list for ReaderDocument objects is stored (~/Library/Application Support/ by default), see the +archiveFilePath: method in the ReaderDocument.m source file. Archiving and unarchiving of the ReaderDocument object for a document is mandatory since this is where the current page number, bookmarks and directory of the document page thumb cache is kept.

Contact Info

Email: joklamcak(at)gmail(dot)com

Twitter: @joklamcak

Acknowledgements

The PDF link support code in the ReaderContentPage class is based on the links navigation code by Sorin Nistor from http://ipdfdev.com/.

License

This code has been made available under the MIT License.

GitHub

https://github.com/vfr/Reader
Comments
  • 1. Fixed crash in iOS 8.

    In iOS 8, the file system layout of app containers has changed on disk. Because of this change, the main .app bundle and the Documents/Library directories are stored in different places on the disk.

    i.e: Application Directory: /private/var/mobile/Containers/Bundle/Application/E49D4518-5F07-425A-B743-03386C4644AF/Reader.app Documents Directory: /var/mobile/Containers/Data/Application/98A0FF1A-F97E-4A6E-B10E-B58E5DCFA72B/Documents

    vfrReader creates a relativePath to store when archiving the ReaderDocument (to handle cases where the user may restore from a backup or use iCloud etc). This was fine in previous versions of iOS because it removes the applicationPath from the filePath of the supplied pdf.

    However, in iOS 8. If i was loading a document from my main bundle (this can be reproduced in the demo app), the document would try to calculate its relativeURL from the NSDocumentDirectory minus the lastPathComponents.

    If you use the two paths from above and try to do that, It is trying to remove /var/mobile/Containers/Data/Application/98A0FF1A-F97E-4A6E-B10E-B58E5DCFA72B/ from /private/var/mobile/Containers/Bundle/Application/E49D4518-5F07-425A-B743-03386C4644AF/Reader.app/Reader.pdf

    This obviously doesn't work as the range.length was NSNotFound causing the application to crash.

    To fix the issue, I have modified the code to remove the _fileName ivar (so it is no longer archived) and to use a new _filePath ivar instead. Because unarchiveFromFileName:password: supported being able to only pass in the lastPathComponent (i.e Reader.pdf). I have had to depreciate this method and I have replaced it with unarchiveFromFilePath:password:.

    The application will still compile fine, but anybody trying to use the old method will have an assertion raised telling them to use the new method. You must pass the absolute filePath into this new method as it will also update the _filePath ivar on the document once it has been unarchived.

    Let me know if you have any more questions. Liam

    Reviewed by liamnichols at 2014-09-01 12:37
  • 2. Added support for iOS7 appearance.

    Allows for setting barTintColor and tintColor to change the look of the Reader. Example:

    ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
    [readerViewController setBarTintColor:[UIColor colorWithRed:0.1 green:0.3 blue:0.8 alpha:0.9]];
    readerViewController.view.tintColor = [UIColor colorWithWhite:1 alpha:1];
    

    This sets both the toolbar and pagebar background color. The buttons and the Done-button text automatically changes color to the tintColor of the ReaderViewController.

    iOS 6 still uses the old appearance.

    Reviewed by klofberg at 2013-11-08 01:30
  • 3. Implement fast-pagination

    Hi - nice project. I have been using this library within a project I am working on and it has been great. One thing that I felt needed improvement was the pagination. When you reached the end of the preloaded pages (3 by default), you will get a "bounce" and have to wait until the scroll view decelerates until you can continue.

    This made it rather difficult to scroll quickly through several pages quickly. I have adjusted the behaviour in this feature branch to fix that annoyance.

    I have made several other customisations to the project, I will likely publish them as separate branches and do pull requests when I think they are ready (and if you'd like them), however I feel this patch is beneficial to almost everyone as it improves user experience.

    Cheers!

    Reviewed by ryanmaxwell at 2013-10-07 02:46
  • 4. Customisable Reader

    When using reader core as a pod, some settings cannot be changed. Now you can customize the toolbar, background colors and shadows. There is also a thumbnails-only view-mode.

    Signed-off-by: Tom Kremer [email protected]

    Reviewed by TomKremer at 2016-10-25 22:27
  • 5. Expose pageWidth and pageHeight of ReaderContentPage to derived classes.

    CONTEXT

    We're using a highly customised version of vfrReader for one of our projects. In order to do various transforms we need to know the size of a ReaderContentPage, but it is not cleanly exposed in the current implementation

    WHAT THIS PR DOES

    This PR simply exposes the 2 variables pageWidth and pageHeight as properties, so that outside (and derived) classes can read them.

    WHY IS IT NECESSARY? Without this change, derived classes have to re-read the page info from the pdf context.

    ALTERNATIVE SOLUTION If you're not keen on exposing this as a property, perhaps it could be made protected using @protected instead?

    Reviewed by cfeckardt at 2016-03-16 15:41
  • 6. Add landscape double page support

    See https://github.com/vfr/Reader/issues/71

    Enable with : LANDSCAPE_DOUBLE_PAGE Enable single first page (for magazines) : LANDSCAPE_SINGLE_FIRST_PAGE

    Patched with minimal changes

    Reviewed by etabard at 2014-11-25 11:12
  • 7. Theming support for toolbars, removed some deprecation warnings

    Hi,

    I have added support for controlling the light and dark color you use in the gradients of the three toolbars. Now you can set the theme colors once for your ReaderViewController and then the toolbars will have their colors set accordingly.

    Furthermore, I removed some deprecation warnings. It still compiles (without warnings) for iOS 5 but I have not tested iOS 4. I guess you don't really support iOS 4 anyway, right?

    Thank you for open sourcing this great PDF viewer!

    Best regards, Mads

    Reviewed by madsdk at 2013-09-03 14:32
  • 8. Various fixes

    --Fix for CATiledLayer crash

    I was getting crashes due to the catiledlayer's delegate not being nilled on dealloc. This fixed it for me and I haven't seen another crash in a few months. The fix is from the following: http://stackoverflow.com/questions/6012796/ios-catiledlayer-crash

    --Resolves an intermittent flickering issue while scrolling

    Looks like there was an attempt to fix this in the past by setting the fade duration to a very small number. I would still get the flicker a certain times and setting the fade duration to 0 fixed it.

    Reviewed by soleares at 2012-10-06 00:14
  • 9. stringByAddingPercentEscapesUsingEncoding Deprecated in 9

    stringByAddingPercentEscapesUsingEncoding is deprecated as of iOS9.0 replaced with stringByAddingPercentEncodingWithAllowedCharacters.

    https://developer.apple.com/documentation/foundation/nsstring/1415058-stringbyaddingpercentescapesusin

    This also addresses a bug where external anchor links with a # in the name are incorrectly encoded to %23. i.e. http://site/index.html#anchor is sent to http://site/index.html%23anchor

    Reference SO https://meta.stackexchange.com/questions/259368/ios-app-url-percent-encoding-and-decoding-bug

    Reviewed by johncarpenter at 2017-06-08 16:14
  • 10. Allow vertical scrolling

    ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
    readerViewController.delegate = self;
    readerViewController.scrollDirection = ReaderScrollDirectionVertical;
    

    The last option is new and allow "top to bottom" scrolling.

    Reviewed by stuffmc at 2017-03-22 10:35
  • 11. Add basic tests and Travis CI

    As part of http://blog.cocoapods.org/Test-Jammin/, I decided to add some basic tests and Travis CI support to this repo.

    The tests exercise:

    • simple PDF validity (and make sure that the filename doesn't matter)
    • page numbers

    Here's an example successful Travis CI run too: https://travis-ci.org/mmmulani/Reader/builds/59030158

    Reviewed by mmmulani at 2015-04-18 13:53
  • 12. Fix for when user scrolls content quickly results in content not being loaded

    I know this is not a supported library any longer, but this is a fix I put in this past summer to fix an issue when a person scrolls pages quickly, it resulted in content not loading, presenting the user with a blank page. This should fix this issue for people that have not updated to a newer library.

    Reviewed by x2rider at 2019-12-30 22:34
Related tags
An iOS PDF viewer and annotator written in Swift that can be embedded into any application.

Requirements iOS 9 or above Xcode 8 or above Swift 3.0 Note This project is still in early stages. Right now the PDF reader works both programmaticall

Jun 27, 2022
TPPDF is a simple-to-use PDF builder for iOS
TPPDF is a simple-to-use PDF builder for iOS

TPPDF is a fast PDF builder for iOS & macOS using simple commands to create advanced documents! Created and maintained by Philip Niedertscheider and a

Jun 10, 2022
Small utility to import PDF slides as vector images into Keynote for iOS.
Small utility to import PDF slides as vector images into Keynote for iOS.

Small utility to import PDF files into Keynote for iOS. This utility is especially helpful when presenting slideshows created by LaTeX

Jun 14, 2022
Draw Week Time Table on PDF using PDFKit in iOS Swift
Draw Week Time Table on PDF using PDFKit in iOS Swift

DrawPDFTimeTable Draw Week Time Table on PDF using PDFKit in iOS Swift. Image Info This is the pdf of time table drawn using PDFKit in iOS Swift with

May 31, 2022
A simple generator of PDF written in Swift.

Features | Requirements | Installation | Usage | Communication | LICENSE PDFGenerator PDFGenerator is a simple PDF generator that generates with UIVie

May 31, 2022
SimplePDF is a wrapper of UIGraphics PDF context written in Swift.
SimplePDF is a wrapper of UIGraphics PDF context written in Swift.

SimplePDF is a wrapper of UIGraphics PDF context written in Swift. You can: add texts, images, spaces and lines, table set up page layout, adjust cont

Jun 7, 2022
PDF generator using UIViews or UIViews with an associated XIB

Description Create UIView objects using any method you like, including interface builder with Auto-layout and size classes enabled. Then generate a PD

Aug 28, 2020
Generate beautiful .pdf Files from xib

Description The Library generates a PDF directly from interface builder with Auto-layouted views! Swift Version of UIView_2_PDF. Installation Download

Sep 23, 2021
UIImage PDF extensions.

UIImagePlusPDF UIImage extensions to use PDF files. Using UIImagePlusPDF you can avoid a lot png images files (1x, 2x, 3x sizes) and simply replace ea

Jan 25, 2022
Estrutura Simples para Navegacao Web e Download PDF

Download-PDF-WebView Projeto desenvolvido em Swift com a função de criar uma estrutura simples para navegação Web em seu Aplicativo, permitindo a visu

Nov 30, 2021
PdfBuilder: a swift library made to make creation of the Pdf file from code simpler
PdfBuilder: a swift library made to make creation of the Pdf file from code simpler

PdfBuilder PdfBuilder is a swift library made to make creation of the Pdf file f

Mar 7, 2022
Mephisto - A command line tool to convert Comic Book Zip archives to PDF and share them over AirDrop
Mephisto - A command line tool to convert Comic Book Zip archives to PDF and share them over AirDrop

mephisto A command line tool written in Swift to convert Comic Book Zip archives

Feb 7, 2022
Swift package that uses WebKit to render PDF files from URLs

Swift package for generating a PDF file from a URL (rendered by WebKit)

Feb 25, 2022
📚 A Swift ePub reader and parser framework for iOS.
📚 A Swift ePub reader and parser framework for iOS.

FolioReaderKit is an ePub reader and parser framework for iOS written in Swift. Features ePub 2 and ePub 3 support Custom Fonts Custom Text Size Text

Jun 19, 2022
About PDFKit learning project on iOS 11, Like iBooks.app.
About PDFKit learning project on iOS 11, Like iBooks.app.

iBook About PDFKit learning project on iOS 11, Like iBooks.app. 书库 书库页面获取PDF相关数据, 可以通过KVC获取。 PDF书名 if let title = documentAttributes["Title"] as? Stri

Jun 23, 2022
A Static Library to be embedded on iOS applications to display pdf documents derived from Fast PDF

FastPdfKit This repository contains the FastPdfKit iOS library with some sample projects. FastPdfKit is a library that let you show pdf documents in i

Jun 17, 2022
An iOS PDF viewer and annotator written in Swift that can be embedded into any application.

Requirements iOS 9 or above Xcode 8 or above Swift 3.0 Note This project is still in early stages. Right now the PDF reader works both programmaticall

Jun 27, 2022
An iOS app that allows you to create resumes on your phone and export them to pdf

Resume Builder iOS An iOS app that allows you to create resumes on your phone and export them to pdf To create a new resume, choose + from the main vi

Oct 25, 2021
TPPDF is a simple-to-use PDF builder for iOS
TPPDF is a simple-to-use PDF builder for iOS

TPPDF is a fast PDF builder for iOS & macOS using simple commands to create advanced documents! Created and maintained by Philip Niedertscheider and a

Jun 10, 2022
Small utility to import PDF slides as vector images into Keynote for iOS.
Small utility to import PDF slides as vector images into Keynote for iOS.

Small utility to import PDF files into Keynote for iOS. This utility is especially helpful when presenting slideshows created by LaTeX

Jun 14, 2022