Some test text!

menu
UI componentskeyboard_arrow_down

Customize a document view controller on iOS

This document refers to the PTDocumentController
For the legacy PTDocumentViewController class, please see this guide.

This article explains how to customize the document viewer classes PTDocumentController and PTTabbedDocumentViewController.

Because the document viewer classes are part of the open source Tools UI framework, it is possible to achieve virtually any required modification. That said, it is usually faster and more convenient to configure the viewers via APIs, which this guide describes.

linkPTDocumentController

Regular

Compact

PTDocumentController

The above image (items 1–5) indicates areas that are controllable via the PTDocumentController's API. Information on customizing these is available directly below.

PTDocumentController

The above image (items 7–12) indicates a number of default buttons that create and present new controls. Information on where to look to customize these presented controls can be found in the component controls table.

On iPad and other regular horizontal size class devices, a number of default UI controls are accessible from the navigation bar, whereas on iPhones and compact size classes some of those controls appear in the toolbar at the bottom of the view.

Image NumberButtonFunctionalityLocation on iPadLocation on iPhone
7searchButtonItemPTTextSearchViewControllernavigationItem.rightBarButtonItemsnavigationItem.rightBarButtonItems
8moreItemsButtonItemPTMoreItemsViewControllernavigationItem.rightBarButtonItemsnavigationItem.rightBarButtonItems
10navigationListsButtonItemPTNavigationListsViewControllernavigationItem.leftBarButtonItemstoolbar
11thumbnailsButtonItemPTThumbnailsViewControllernavigationItem.leftBarButtonItemstoolbar
12readerModeButtonItemPTReflowViewControllernavigationItem.rightBarButtonItemstoolbar

link1: Toolbar switcher

linkHide the toolbar switcher

The toolbar switcher can be hidden:

documentController.toolGroupIndicatorView.isHidden = true

linkRemove toolbars from the switcher

Toolbars can be removed by removing them from the toolGroupManager's groups array. The following code removes the "Draw" and "Pens" toolbars:

var mutableGroups = documentController.toolGroupManager.groups

let groupsToRemove = [documentController.toolGroupManager.drawItemGroup, documentController.toolGroupManager.pensItemGroup]

mutableGroups.removeAll(where: {groupsToRemove.contains($0)})

documentController.toolGroupManager.groups = mutableGroups

link2: Navigation bar items

The buttons which are contained in the leftBarButtonItems and rightBarButtonItems arrays, are completely customizable. It is possible to

  • Add buttons
  • Remove (hide) buttons
  • Move buttons
  • Change icons

linkAdd buttons

You can modify the navigation bar items. Here is an example of adding a new button (for the current size class):

let myItem = UIBarButtonItem(image: UIImage(systemName:"square.and.pencil"), style: .plain, target: nil, action: nil)

documentController.navigationItem.rightBarButtonItems.append(myItem)

Tools can also be added:

let freeHand = documentController.toolGroupManager.createItem(forToolClass:PTFreeHandCreate.self)

documentController.navigationItem.rightBarButtonItems.append(freeHand)

Note that in the example above, de-selecting the tool button item needs to be implemented by the app, by listening to the Tool Did Change notification.

linkRemove buttons

To remove any of the default buttons see the instructions here: Hide default buttons

linkMove buttons

The default buttons are all accessible via properties, making it easy to rearrange or move them. The following code swaps the position of the search button and navigation lists button:

var rightItems = documentViewController.navigationItem.rightBarButtonItems
rightItems?.removeAll(where: { element in element == documentViewController.searchButtonItem })
rightItems?.append(documentViewController.navigationListsButtonItem)

var bottomRightItems:[UIBarButtonItem]? = documentViewController.thumbnailSliderController.trailingToolbarItems
bottomRightItems?.removeAll(where: { element in element as NSObject == documentViewController.navigationListsButtonItem })
bottomRightItems?.append(documentViewController.searchButtonItem)

documentViewController.navigationItem.rightBarButtonItems = rightItems
documentViewController.thumbnailSliderController.trailingToolbarItems = bottomRightItems

linkChange icons

The icons of existing buttons may be changed by creating new UIBarButtonItems that have the same target and action as an existing item, and replacing the existing item with the new item:

// new search UIBarButtonItem
let newSearchItem = UIBarButtonItem(barButtonSystemItem: .search, target: documentController.searchButtonItem.target, action: documentController.searchButtonItem.action)

// replace old search UIBarButtonItem with new search UIBarButtonItem
index = (rightItems as NSArray?)?.index(of: documentController.searchButtonItem)
rightItems?.removeAll(where: { element in element == documentController.searchButtonItem })
rightItems?.insert(newSearchItem, at: index ?? 0)

// update the icons
documentController.navigationItem.rightBarButtonItems = rightItems

link3: Annotation toolbar

The currently-visible annotation toolbar is selected with the toolbar switcher.

linkHide (and show) the annotation toolbar

The toolbar can be programmatically hidden by setting the mode to view group, which is a special group and the only group where the toolbar is hidden:

documentController.toolGroupManager.selectedGroup = documentController.toolGroupManager.viewItemGroup

The toolbar can be shown again by changing the group to any group other than view:

documentController.toolGroupManager.selectedGroup = documentController.toolGroupManager.drawItemGroup

linkRemove buttons from a toolbar

The example below shows how to remove the text highlight and text underline button from a toolbar.

Disabling a tool type entirely

If you want to disable a tool entirely, from all toolbars and the long press menu, please use the annotations permissions system.

let annotateGroup = documentController.toolGroupManager.annotateItemGroup

// tool buttons that exist currently
let defaultAnnotateGroupTools = annotateGroup.barButtonItems

// new set of tools to replace current ones
var newAnnotateGroupTools = [UIBarButtonItem]()

// add all currently existing tools except for the ones we don't want
for defaultToolItem in defaultAnnotateGroupTools
{
    if defaultToolItem.isKind(of: PTToolBarButtonItem.self) {
        let toolBarButton = defaultToolItem as! PTToolBarButtonItem
        if toolBarButton.toolClass == PTTextHighlightCreate.self ||
            toolBarButton.toolClass == PTTextUnderlineCreate.self
        {
            // do not add this tool
            continue
        }
        else
        {
            newAnnotateGroupTools.append(toolBarButton)
        }
    }
    else
    {
        newAnnotateGroupTools.append(defaultToolItem)
    }
}

// assign tools to new array
documentController.toolGroupManager.annotateItemGroup.barButtonItems = newAnnotateGroupTools

linkAdd a tool button to a toolbar

// create a mutable array of the current items in the annotation toolbar group
var availableTools:[UIBarButtonItem] = documentController.toolGroupManager.annotateItemGroup.barButtonItems

// create a new toolbar item for freehand annotations
let freeHandItem = documentController.toolGroupManager.createItem(forToolClass: PTFreeHandCreate.self)

// add the freehand annotation item to the front of the list
availableTools.insert(freeHandItem, at: 0)

// assign the array back to the annotation toolbar group.
documentController.toolGroupManager.annotateItemGroup.barButtonItems = availableTools

linkAdd a button with fully custom behavior

Your app may need a button that does not invoke one of the built in annotation tools. The following code will add a button that calls a selector.

let selectableItem = PTSelectableBarButtonItem(image: UIImage(systemName:"square.and.pencil"), style: .plain, target: self, action: #selector(customToolAction(_:)))
selectableItem.title = "Custom Tool"

documentController.toolGroupManager.annotateItemGroup.barButtonItems.append(selectableItem)

If you want to toggle the items selection, flip its selected property:

@objc func customToolAction(_ button:PTSelectableBarButtonItem)
{
    button.isSelected = !button.isSelected
}

link4: Page number indicator

The page indicator can be enabled/disabled via the pageIndicatorEnabled property.

link5: PDFViewCtrl

The PTPDFViewCtrl is a UIView that displays the PDF. It is customizable via is properties/methods and delegate methods.

For an overview see the PTPDFViewCtrl Guide, or the detailed API documentation.

Note that all PDF "interaction" (annotations, form filling, text selection, link following, etc.) is supplementary to the PDFViewCtrl, and is implemented in the open source tools.framework.

link6. Toolbar (iPhone only)

These are the buttons that appear at the bottom of the screen on iPhones and in Compact horizontal size classes. Buttons can be added, removed, or rearranged with convenient APIs.

linkAdd buttons to toolbar

// new button
let myItem = UIBarButtonItem(image: UIImage(systemName:"square.and.pencil"), style: .plain, target: nil, action: nil)

// spacer to keep evenly spaced buttons
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

// new array
var toolbarItems = documentController.toolbarItems

// add the new items
toolbarItems.append(contentsOf: [spacer, myItem])

// set the toolbarItems to the new items
documentController.toolbarItems = toolbarItems

linkRemove buttons from toolbar

To remove any of the default buttons see the instructions here: Hide default buttons

link7-12: Controls Presented by a PTDocumentController

To customize the controls that are presented by the PTDocumentController's default buttons, please see the corresponding guide or API:

Image numberControl
7PTTextSearchViewController
8PTMoreItemsViewController
9PTPageIndicatorViewController
10PTNavigationListsViewController
11PTThumbnailsViewController
12PTReflowViewController

linkHide default buttons

Default buttons can be removed ("hidden") using built-in properties.

For example to hide the search and more items buttons:

documentController.searchButtonHidden = true
documentController.moreItemsButtonHidden = true

linkPTTabbedDocumentViewController

The tabbed document view controller displays a collection of document controllers in tabs.

linkTab Settings

Tabs can be disabled using the tabsEnabled property, and the maximum number of allowed tabs can be set using maximumTabCount.

linkAccess to child PTDocumentControllers

The current document controller can be accessed via selectedViewController, and others via documentViewController(at:)

To configure a document controller before it is displayed, conform to and implement the PTTabbedDocumentViewControllerDelegate method tabbedDocumentViewController(_:willAdd:). Note that it is permissible to assign the internal PTDocumentViewController's delegate to an external object.

func tabbedDocumentViewController(_ tabbedDocumentViewController: PTTabbedDocumentViewController, willAdd documentViewController: PTDocumentViewController) {
        documentViewController.delegate = self
        // customize documentViewController
    }

linkSummary

APIFunctionality
tabsEnabledEnables/disables tabs.
maximumTabCountControls the maximum number of concurrent tabs.
selectedViewControllerThe current PTDocumentViewController.
documentViewController(at:)The PTDocumentViewController at the given index.
tabbedDocumentViewController(_:willAdd:)Access to a PTDocumentViewController that is about to be displayed.

Get the answers you need: Support

close

Free Trial

Get unlimited trial usage of PDFTron SDK to bring accurate, reliable, and fast document processing capabilities to any application or workflow.

Select a platform to get started with your free trial.

Unlimited usage. No email address required.

Join our upcoming webinar to learn about how to collaborate on videos frame by frame directly in your browser

Save your seat
close