Latest 0.4.0
License MIT
Platforms ios 8.0
Frameworks UIKit

CI Status


TPPDF is a PDF builder for iOS, based on the Builder pattern using simple commands.


  • :white_check_mark: Page header and footer
  • :white_check_mark: Dynamic content layout with page alignment
  • :white_check_mark: Support for tables and cell alignment
  • :white_check_mark: Attributed strings
  • :white_check_mark: Custom spacing
  • :white_check_mark: Image support
  • :white_check_mark: Horizontal line separators
  • :white_check_mark: Custom indentation
  • :white_check_mark: Custom top offset (good for layered rendering)
  • :white_check_mark: Pagination
  • :white_check_mark: Image caption
  • :white_check_mark: Compress images
  • :white_check_mark: Custom image size fit
  • :white_check_mark: Image in the header and footer
  • :white_check_mark: Horizontal line separators in the header and footer
  • :white_check_mark: Generate PDF files directly to handle large PDF files (Details)
  • :white_check_mark: PDF metadata
  • :white_check_mark: Custom table styling
  • You need more features? Checkout #Contribute


Language Branch Pod version Xcode version iOS version
Swift 3.0 master >= 0.2.x Xcode 8 or greater iOS 8.0+
Swift 2.3 swift-2.3 0.1.5 Xcode 8, Xcode 7.3.x iOS 8.0+
Swift 2.2 swift-2.2 0.1.4 Xcode 7.3.x iOS 8.0+


  • If you need help, use Stack Overflow. (Tag ‘TPPDF’)
  • If you’d like to ask a general question, use Stack Overflow.
  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.



CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate TPPDF into your Xcode project using CocoaPods, specify it in your Podfile:

source ''
platform :ios, '10.0'

target '<Your Target Name>' do
    pod 'TPPDF'

Then, run the following command:

$ pod install


Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate TPPDF into your Xcode project using Carthage, specify it in your Cartfile:

github "Techprimate/TPPDF" ~> 0.4

Run carthage update to build the framework and drag the built Alamofire.framework into your Xcode project

Swift Package Manager

Swift Package Manager is not supported, as it is currently built for MacOS and Linux and therefore can’t require the framework UIKit


If you prefer not to use either of the aforementioned dependency managers, you can integrate TPPDF into your project manually.

Embedded Framework

  • Open up Terminal, cd into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:
$ git init
  • Add TPPDF as a git submodule by running the following command:
$ git submodule add
  • Open the new TPPDF folder, and drag the TPPDF.xcodeproj into the Project Navigator of your application’s Xcode project.

    It should appear nested underneath your application’s blue project icon. Whether it is above or below all the other Xcode groups does not matter.

  • Select the TPPDF.xcodeproj in the Project Navigator and verify the deployment target matches that of your application target.
  • Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.
  • In the tab bar at the top of that window, open the "General" panel.
  • Click on the + button under the "Embedded Binaries" section.
  • You will see two different TPPDF.xcodeproj folders each with two different versions of the TPPDF.framework nested inside a Products folder.

    It does not matter which Products folder you choose from, but it does matter whether you choose the top or bottom TPPDF.framework.

  • Select the top TPPDF.framework for iOS and the bottom one for OS X.

    You can verify which one you selected by inspecting the build log for your project. The build target for TPPDF will be listed as either TPPDF iOS or TPPDF OSX.

  • And that’s it!

The TPPDF.framework is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.


To run the example project, clone the repo, and run pod install from the Example directory first.


If you want to see a fully working example, please try the Cocoapod using pod try TPPDF.

TPPDF creates a PDF based on commands. When the generator starts to build the PDF file it calls one command after another, until no commands are left.


Every command is associated to a specific container. Three containers exist: Header, Content, Footer. Additionally every container has an alignment: Left, Center, Right.

When registering a command you provide the correct container – the default container is ContentLeft. When the PDFGenerator performs the commands, it applies the to the correct container. This way you can identify which area of the PDF gets changed.

A good example would be the following call:

let pdf = PDFGenerator(format: .a4)
pdf.addText(.footerCenter, text: "Created using TPPDF for iOS.")

This command adds the text "Created using TPPDF for iOS" to the footer of all pages.


The following values can be set to format the page:

  • size
  • margin
  • headerMargin
  • footerMargin
  • headerSpace
  • footerSpace

All values are in dots and are rendered using 72 DPI (dots per inch), as this is the default screen DPI.

You can also used the predefined formats. For details please refer to the source file PageFormat.swift

If you need your page in landscape format, use the landscapeSize variable.

Header & Footer

If you want to add a text to the header or footer you simply need to choose the correct container.

If you want to render an image in one of these containers, it will use the square size headerImageHeight.

But there are some limitations:

  • Only one line. If you want multiple lines, add multiple commands


To enable pagination, set a Container on the variable paginationContainer.

Image Quality

To reduce the amount of data and the resulting file size, you can reduce the image quality by setting a value between 0 and 1 on the variable imageQuality.

PDF Info

Configure PDF metadata, including title, author, subject, keywords, owner password, user password, allows printing, and allows copying.


The following commands are the ones available to you for creating your document. Most of these take a container as a parameter, defaulting to page content with left alignment. For the sake of readability, there is only a container in the example of addText(...).


  • addLineSeparator(container, style)

Draws a horizontal line using the given line style in the given container.

pdf.addLineSeparator(thickness: 0.1, style: LineStyle(type: .dashed, color:, width: 1.0))


  • addText(container, text, lineSpacing)

Draws a text in the given container. It creates a attributed string and sets the linespacing.

pdf.addText(.ContentCenter, text: "Created using TPPDF for iOS.", lineSpacing: 5)
  • addAttributedText(container, attributedText)

Draws a NSAttributedString in the given container.

let title = NSMutableAttributedString(string: "Awesome attributed title!", attributes: [
    NSFontAttributeName : UIFont.systemFontOfSize(28.0),
    NSForegroundColorAttributeName : UIColor(red: 219.0 / 255.0, green: 100.0 / 255.0, blue: 58.0 / 255.0, alpha: 1.0)
pdf.addAttributedText(text: title)
  • setFont(container, font)

Sets the font of a container. This font will be used in the next commands in the given container, if there is not a different font specified.

pdf.setFont(UIFont.systemFont(ofSize: 20.0))
  • resetFont(container)

This resets the font to the default font, which is UIFont.systemFont(ofSize: UIFont.systemFontSize)



  • addImage(container, image, size, caption, sizeFit)

Draws an image in the given container. If the given size is not zero size, it will draw it using that size, proportionally scaling. The size of an image is scaled according to sizeFit. If the height of an image and its caption is beyond the page bounds, then a new page is created. The caption is an attributed string and can be styled (refer to addAttributedText(...) for an example).

pdf.addImage(image: UIImage(named: "Image.jpg")!)
  • addImagesInRow(container, images, captions, spacing)

Draws images with captions in the row using the given spacing in the given container.

pdf.addImagesInRow(images: [UIImage(named: "image.jpg")!, UIImage(named: "PortraitImage.jpg")!], captions: [NSAttributedString(string: "Caption 1"), NSAttributedString(string: "Caption 2")])


  • addTable(container, data, alignment, relativeColumnWidth, padding, margin, style)

Draws a table in the given container.

The parameter data is a two-dimensional String array

let data: [[String]] = [
    ["Rating",     "4.5 / 5",  "PrepnTime:",   "14 Hours"    ],
    ["Portions:",   "14",       "CooknTime:",   "16 Minutes" ]

The parameter alignment is a two-dimensional array with TableCellAlignment values.

let alignments: [[TableCellAlignment]] = [
    [.Left, .Center, .Left, .Center],
    [.Left, .Center, .Left, .Center]

The parameter relativeColumnWidth is an array of CGFloat smaller or equal than 1.0
These are relative widths in percentage to the full page content width (= page width – 2 * page margin). It defines the width of each column.

let widths: [CGFloat] = [
    0.3, 0.2, 0.3, 0.2

The data array and the alignments array must contain the equal amount of items. The widths array must have the same amount as the data array columns has.

Additional parameters are cell margin and cell padding. Margin is the spacing between each cell or between the cell and the table bounds. Padding is the spacing between the content of the cell to the cell bounds.

This works the same way as HTML/CSS margin and padding works. Checkout margin and padding

Table styling is done with a TableStyle object. TableStyleDefaults contain a couple of predefined table styles, which can be modified.
A table style consists out of five different styles, for the row header, column header, footer, content and for alternating rows. It is also possible to set custom cell styling using the method setCellStyle(row, column, style).

Cell styling includes background fill color, text color, font and the line style for each border.

Line styling includes line color, line width and line type, which can be either non, full, dashed or dotted.

let tableStyle = TableStyleDefaults.simple

tableStyle.setCellStyle(row: 2, column: 3, style: TableCellStyle(fillColor: .yellow, textColor: .blue, font: UIFont.boldSystemFont(ofSize: 18)))
tableStyle.setCellStyle(row: 20, column: 1, style: TableCellStyle(fillColor: .yellow, textColor: .blue, font: UIFont.boldSystemFont(ofSize: 18)))

pdf.addTable(data: tableData, alignment: tableAlignment, relativeColumnWidth: tableWidth, padding: 8, margin: 0, style: tableStyle)


  • addSpace(container, space)

Adds the given value to the content height, resulting in a space between the previous and the next command element.

pdf.addSpace(space: 12.0)
  • setIndentation(container, points)

If you need to indent your content you can simply call this method.

pdf.setIndentation(indent: 50.0)

Now add more commands which are indented.
If you need to reset the indentation simply call the function with 0.0 as parameter

pdf.setIndentation(indent: 0.0)
  • setAbsoluteOffset(container, points)

If you do not want to add a space between two elements, you can also set a absolut offset form the top border.

One possible use case are layered PDF files.
Simply call pdf.setOffset(offset: 0.0) and you can add content which is placed on top of the previously set content.

pdf.setOffset(offset: 250.0)
  • createNewPage()

Create a new page.



You need more commands?
Just fork the project, implement the following and create a pull request!

To implement a new command you need to edit the following places. As an example we implement the command SetFont:

enum Command {
case SetFont(font: UIFont)
  • Add SetFont to the switch statement in the method renderCommand in PDFGenerator.swift. In this case you do not need to create another draw... method but in other cases you might have to create a new private drawing method, handling different containers.
switch command {
   case let .SetFont(font):
        self.font = font // Currently there is one font variable used for draw calls. If you change it, all future commands will use the new font.
  • Add a public method setFont which adds a command to the command chain.
public func setFont(container: Container = Container.ContentLeft, font: UIFont = UIFont.systemFontOfSize(14)) {
    commands += [(container, .SetFont(font: font))]

If you add default values, then you need to do it in this method!

Aspects to consider!!

The previous example does not handle different Containers. The correct way of doing this, would be three instance variables of type UIFont. One for the header, one for the content and one for the footer.
Then, when calling the command, it changes the correct font variable, depending on the Container provided.

Apps using TPPDF

If you are using TPPDF in your app and want to be listed here, simply create a pull request or let me know on twitter or via github. I am always curious who is using my projects :)

Hikingbook – by Zheng-Xiang Ke


Bug Journal – by David Johnson

Bug Journal

Mama’s Cookbook (future release) – by Philip Niedertscheider

Mama's Cookbook


TPPDF is created by Philip Niedertscheider.

Special thanks goes to Nutchaphon Rewik for his project SimplePDF for the inspiration and code base.



TPPDF is available under the MIT license. See the LICENSE file for more info.

Latest podspec

    "name": "TPPDF",
    "version": "0.4.0",
    "summary": "TPPDF is a simple-to-use PDF builder for iOS",
    "description": "TPPDF is a PDF builder based on the 'Builder' pattern. It uses the built-in framework for generating PDF files.",
    "homepage": "",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    "authors": {
        "Philip Niedertscheider": "[email protected]"
    "source": {
        "git": "",
        "tag": "0.4.0"
    "social_media_url": "",
    "platforms": {
        "ios": "8.0"
    "source_files": "Sources/**/*",
    "frameworks": "UIKit",
    "pushed_with_swift_version": "3.0"

Pin It on Pinterest

Share This