> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/ios/ui-customization/viewer-configuration.md).

# Customize a document view controller on iOS

Learn how to customize the PTDocumentController and PTTabbedDocumentViewController classes for your document viewer needs. Find out how to modify UI controls and functionalities with this comprehensiv

{% hint style="info" %}
**This document refers to the PTDocumentController**

For the legacy `PTDocumentViewController` class, please see [this guide ](/ios/basic-operations/basics/viewer/viewer-configuration-legacy.md).
{% endhint %}

This article explains how to customize the document viewer classes [`PTDocumentController`](https://sdk.apryse.com/api/ios/Classes/PTDocumentController.html) and [`PTTabbedDocumentViewController`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html).

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.

## PTDocumentController

{% tabs %}
{% tab title="Regular" %}
![](https://4149080208-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgY6xtY9ZQd9XMpvWlGM0%2Fuploads%2Fgit-blob-f0923ebc5cc3ed865624052e94057f42968c41aa%2Ff68cb83052a7d9d84680780e384a7383227592c1-1024x665.png?alt=media)

The above image (items 1–5) indicates areas that are controllable via the `PTDocumentController`'s API. Information on customizing these is available [directly below](#1:-toolbar-switcher).

![](https://4149080208-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgY6xtY9ZQd9XMpvWlGM0%2Fuploads%2Fgit-blob-441ef7cb126d5a63dfc3af2d2a6bd790154ed851%2F29fc6dcd8e42064fe759031d2c7f11c386ac718d-1024x200.png?alt=media)

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](https://docs.apryse.com).
{% endtab %}

{% tab title="Compact" %}
![](https://4149080208-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgY6xtY9ZQd9XMpvWlGM0%2Fuploads%2Fgit-blob-998e765d6f32707e13e7829baa79b67c5c6d1081%2Fe194a3ad168c7f597b0bf1b2394c94e5b3c512ee-1024x715.png?alt=media)

The **image on the left** (items 1–6) indicates areas that are controllable via the `PTDocumentController`'s API. Information on customizing these is available [directly below](#1:-toolbar-switcher).

The **image on the right** (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](https://docs.apryse.com).
{% endtab %}
{% endtabs %}

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 Number | Button                    | Functionality                                                                                        | Location on iPad                   | Location on iPhone                 |
| ------------ | ------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------- | ---------------------------------- |
| 7            | searchButtonItem          | [PTTextSearchViewController](/ios/search/text.md)                                                    | navigationItem.rightBarButtonItems | navigationItem.rightBarButtonItems |
| 8            | moreItemsButtonItem       | [`PTMoreItemsViewController`](https://sdk.apryse.com/api/ios/Classes/PTMoreItemsViewController.html) | navigationItem.rightBarButtonItems | navigationItem.rightBarButtonItems |
| 10           | navigationListsButtonItem | [`PTNavigationListsViewController`](/ios/ui-customization/navigation-lists.md#customization)         | navigationItem.leftBarButtonItems  | toolbar                            |
| 11           | thumbnailsButtonItem      | [`PTThumbnailsViewController`](/ios/page-manipulation/thumbnails-view-i.md)                          | navigationItem.leftBarButtonItems  | toolbar                            |
| 12           | readerModeButtonItem      | [`PTReflowViewController`](/ios/viewer/view-mode.md#reflow)                                          | navigationItem.rightBarButtonItems | toolbar                            |

### 1: Toolbar switcher

#### Hide the toolbar switcher

The toolbar switcher can be hidden:

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
documentController.toolGroupIndicatorView.isHidden = true
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
documentController.toolGroupIndicatorView.hidden = YES;
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Remove 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:

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
var mutableGroups = documentController.toolGroupManager.groups

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

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

documentController.toolGroupManager.groups = mutableGroups
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
NSMutableArray<PTToolGroup*>* mutableGroups = [documentController.toolGroupManager.groups mutableCopy];
    
[mutableGroups removeObjectsInArray:@[documentController.toolGroupManager.drawItemGroup, documentController.toolGroupManager.pensItemGroup]];
    
documentController.toolGroupManager.groups = [mutableGroups copy];
```

{% endcode %}
{% endtab %}
{% endtabs %}

### 2: Navigation bar items

The buttons which are contained in the [`leftBarButtonItems`](https://developer.apple.com/uikit/uinavigationitem/1624946-leftbarbuttonitems/) and [`rightBarButtonItems`](https://developer.apple.com/uikit/uinavigationitem/1624956-rightbarbuttonitems/) arrays, are completely customizable. It is possible to

* [Add buttons](#add-buttons)
* [Remove (hide) buttons](#remove-buttons)
* [Move buttons](#move-buttons)
* [Change icons](#change-icons)

#### Add buttons

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

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

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

documentController.navigationItem.rightBarButtonItems.append(myItem)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
UIBarButtonItem* myItem = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"square.and.pencil"] style:UIBarButtonItemStylePlain target:nil action:nil];

documentController.navigationItem.rightBarButtonItems = [documentController.navigationItem.rightBarButtonItems arrayByAddingObject:myItem];
```

{% endcode %}
{% endtab %}
{% endtabs %}

Tools can also be added:

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

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

documentController.navigationItem.rightBarButtonItems.append(freeHand)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
UIBarButtonItem* freeHand = [documentController.toolGroupManager createItemForToolClass:[PTFreeHandCreate class]];

documentController.navigationItem.rightBarButtonItems = [documentController.navigationItem.rightBarButtonItems arrayByAddingObject:freeHand];
```

{% endcode %}
{% endtab %}
{% endtabs %}

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.

#### Remove buttons

To remove any of the default buttons see the instructions here: [Hide default buttons](https://developer.apple.com/uikit/uinavigationitem/1624946-leftbarbuttonitems/)

#### Move 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:

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
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
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
NSMutableArray* rightItems = [documentViewController.navigationItem.rightBarButtonItems mutableCopy];
[rightItems removeObject:documentViewController.searchButtonItem];
[rightItems addObject:documentViewController.navigationListsButtonItem];

NSMutableArray* bottomRightItems = [documentViewController.thumbnailSliderController.trailingToolbarItems mutableCopy];
[bottomRightItems removeObject:documentViewController.navigationListsButtonItem];
[bottomRightItems addObject:documentViewController.searchButtonItem];

documentViewController.navigationItem.rightBarButtonItems = [rightItems copy];
documentViewController.thumbnailSliderController.trailingToolbarItems = [bottomRightItems copy];
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Change 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:

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
// 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
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
// new search UIBarButtonItem
UIBarButtonItem* newSearchItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:documentController.searchButtonItem.target action:documentController.searchButtonItem.action];

// replace old search UIBarButtonItem with new search UIBarButtonItem
index = [rightItems indexOfObject:documentController.searchButtonItem];
[rightItems removeObject:documentController.searchButtonItem];
[rightItems insertObject:newSearchItem atIndex:index];

// update the icons
documentController.navigationItem.rightBarButtonItems = [rightItems copy];
```

{% endcode %}
{% endtab %}
{% endtabs %}

### 3: Annotation toolbar

The currently-visible annotation toolbar is selected with the [toolbar switcher](https://docs.apryse.com).

#### Hide (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:

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
documentController.toolGroupManager.selectedGroup = documentController.toolGroupManager.viewItemGroup
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
documentController.toolGroupManager.selectedGroup = documentController.toolGroupManager.viewItemGroup;
```

{% endcode %}
{% endtab %}
{% endtabs %}

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

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
documentController.toolGroupManager.selectedGroup = documentController.toolGroupManager.drawItemGroup
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
documentController.toolGroupManager.selectedGroup = documentController.toolGroupManager.drawItemGroup;
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Remove 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](/ios/annotation/customization.md#create-and-edit-annotations) system.

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
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
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
PTToolItemGroup* annotateGroup = documentController.toolGroupManager.annotateItemGroup;

// tool buttons that exist currently
NSArray<UIBarButtonItem*>* defaultAnnotateGroupTools = annotateGroup.barButtonItems;

// new set of tools to replace current ones
NSMutableArray<UIBarButtonItem*>* newAnnotateGroupTools = [[NSMutableArray alloc] init];

// add all currently existing tools except for the ones we don't want
for(UIBarButtonItem* defaultToolItem in defaultAnnotateGroupTools)
{
    if( [defaultToolItem isKindOfClass:[PTToolBarButtonItem class]] )
    {
        PTToolBarButtonItem* toolBarButton = (PTToolBarButtonItem*)defaultToolItem;
        
        if( toolBarButton.toolClass == [PTTextHighlightCreate class] ||
             toolBarButton.toolClass == [PTTextUnderlineCreate class] )
        {
            // do not add this tool
            continue;
        }
        else
        {
            [newAnnotateGroupTools addObject:defaultToolItem];
        }
    }
    else
    {
        [newAnnotateGroupTools addObject:defaultToolItem];
    }
}

// assign tools to new array
documentController.toolGroupManager.annotateItemGroup.barButtonItems = [newAnnotateGroupTools copy];
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Add a tool button to a toolbar

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
// 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
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
// create a mutable array of the current items in the annotation toolbar group
NSMutableArray<UIBarButtonItem*>* availableTools = [documentController.toolGroupManager.annotateItemGroup.barButtonItems mutableCopy];

// create a new toolbar item for freehand annotations
UIBarButtonItem* freeHandItem = [documentController.toolGroupManager createItemForToolClass:[PTFreeHandCreate class]];

// add the freehand annotation item to the front of the list
[availableTools insertObject:freeHandItem atIndex:0];

// assign the array back to the annotation toolbar group.
documentController.toolGroupManager.annotateItemGroup.barButtonItems = [availableTools copy];
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Add 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.

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
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)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
PTSelectableBarButtonItem* selectableItem = [[PTSelectableBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(customToolAction:)];
selectableItem.title = @"Custom Tool";

documentController.toolGroupManager.annotateItemGroup.barButtonItems = [documentController.toolGroupManager.annotateItemGroup.barButtonItems arrayByAddingObject:selectableItem];
```

{% endcode %}
{% endtab %}
{% endtabs %}

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

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

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

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
-(void)customToolAction:(PTSelectableBarButtonItem*)button
{
    button.selected = !button.selected;
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### 4: Page number indicator

The page indicator can be enabled/disabled via the [`pageIndicatorEnabled`](https://sdk.apryse.com/api/ios/Classes/PTDocumentBaseViewController.html#/c:objc\(cs\)PTDocumentBaseViewController\(py\)pageIndicatorEnabled) property.

### 5: 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 ](/ios/basic-operations/basics/viewer/pdfviewctrl.md#customize-a-ptpdfviewctrl), or the detailed [API documentation](https://sdk.apryse.com/api/ios/Classes/PTPDFViewCtrl.html).

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`](/ios/annotation/overview.md).

### 6. 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.

#### Add buttons to toolbar

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
// 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
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
// new button
UIBarButtonItem* myItem = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"square.and.pencil"] style:UIBarButtonItemStylePlain target:nil action:nil];
   
// spacer to keep evenly spaced buttons
UIBarButtonItem* spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

// new array
NSMutableArray* toolbarItems = [documentController.toolbarItems mutableCopy];

// add the new items
[toolbarItems addObjectsFromArray:@[spacer, myItem]];

// set the toolbarItems to the new items
documentController.toolbarItems = [toolbarItems copy];
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Remove buttons from toolbar

To remove any of the default buttons see the instructions here: [Hide default buttons](https://docs.apryse.com)

### 7-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 number | Control                                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------------------ |
| 7            | [`PTTextSearchViewController`](/ios/search/text.md)                                                          |
| 8            | [`PTMoreItemsViewController`](https://sdk.apryse.com/api/ios/Classes/PTMoreItemsViewController.html)         |
| 9            | [`PTPageIndicatorViewController`](https://sdk.apryse.com/api/ios/Classes/PTPageIndicatorViewController.html) |
| 10           | [`PTNavigationListsViewController`](/ios/ui-customization/navigation-lists.md#customization)                 |
| 11           | [`PTThumbnailsViewController`](/ios/page-manipulation/thumbnails-view-i.md)                                  |
| 12           | [`PTReflowViewController`](/ios/viewer/view-mode.md#reflow)                                                  |

#### Hide default buttons

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

* [`searchButtonHidden`](https://sdk.apryse.com/api/ios/Classes/PTDocumentBaseViewController.html#/c:objc\(cs\)PTDocumentBaseViewController\(py\)searchButtonHidden)
* [`moreItemsButtonHidden`](https://sdk.apryse.com/api/ios/Classes/PTDocumentBaseViewController.html#/c:objc\(cs\)PTDocumentBaseViewController\(py\)moreItemsButtonHidden)
* [`navigationListsButtonHidden`](https://sdk.apryse.com/api/ios/Classes/PTDocumentBaseViewController.html#/c:objc\(cs\)PTDocumentBaseViewController\(py\)navigationListsButtonHidden)
* [`thumbnailBrowserButtonHidden`](https://sdk.apryse.com/api/ios/Classes/PTDocumentBaseViewController.html#/c:objc\(cs\)PTDocumentBaseViewController\(py\)thumbnailBrowserButtonHidden)
* [`readerModeButtonHidden`](https://sdk.apryse.com/api/ios/Classes/PTDocumentBaseViewController.html#/c:objc\(cs\)PTDocumentBaseViewController\(py\)readerModeButtonHidden)

For example to hide the search and more items buttons:

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
documentController.searchButtonHidden = true
documentController.moreItemsButtonHidden = true
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
documentController.searchButtonHidden = YES;
documentController.moreItemsButtonHidden = YES;
```

{% endcode %}
{% endtab %}
{% endtabs %}

## PTTabbedDocumentViewController

The [tabbed document view controller](https://docs.apryse.com) displays a collection of [document controllers](https://sdk.apryse.com/api/ios/Classes/PTDocumentController.html) in tabs.

### Tab Settings

Tabs can be disabled using the [`tabsEnabled`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html#/c:objc\(cs\)PTTabbedDocumentViewController\(py\)tabsEnabled) property, and the maximum number of allowed tabs can be set using [`maximumTabCount`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html#/c:objc\(cs\)PTTabbedDocumentViewController\(py\)maximumTabCount).

### Access to child PTDocumentControllers

The current document controller can be accessed via [`selectedViewController`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html#/c:objc\(cs\)PTTabbedDocumentViewController\(py\)selectedViewController), and others via [`documentViewController(at:)`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html#/c:objc\(cs\)PTTabbedDocumentViewController\(im\)documentViewControllerAtIndex:)

To configure a document controller before it is displayed, conform to and implement the [`PTTabbedDocumentViewControllerDelegate`](https://sdk.apryse.com/api/ios/Protocols/PTTabbedDocumentViewControllerDelegate.html#/c:objc\(pl\)PTTabbedDocumentViewControllerDelegate\(im\)tabbedDocumentViewController:willAddDocumentViewController:) method [`tabbedDocumentViewController(_:willAdd:)`](https://sdk.apryse.com/api/ios/Protocols/PTTabbedDocumentViewControllerDelegate.html#/c:objc\(pl\)PTTabbedDocumentViewControllerDelegate\(im\)tabbedDocumentViewController:willAddDocumentViewController:). Note that it **is** permissible to assign the internal `PTDocumentViewController`'s delegate to an external object.

{% tabs %}
{% tab title="Swift" %}
{% code lineNumbers="true" %}

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

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
-(void)tabbedDocumentViewController:(PTTabbedDocumentViewController *)tabbedDocumentViewController willAddDocumentViewController:(PTDocumentViewController *)documentViewController
{
    documentViewController.delegate = self;
    // customize documentViewController
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Summary

| API                                                                                                                                                                                                                                                     | Functionality                                                         |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| [`tabsEnabled`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html#/c:objc\(cs\)PTTabbedDocumentViewController\(py\)tabsEnabled)                                                                                                | Enables/disables tabs.                                                |
| [`maximumTabCount`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html#/c:objc\(cs\)PTTabbedDocumentViewController\(py\)maximumTabCount)                                                                                        | Controls the maximum number of concurrent tabs.                       |
| [`selectedViewController`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html#/c:objc\(cs\)PTTabbedDocumentViewController\(py\)selectedViewController)                                                                          | The current `PTDocumentViewController`.                               |
| [`documentViewController(at:)`](https://sdk.apryse.com/api/ios/Classes/PTTabbedDocumentViewController.html#/c:objc\(cs\)PTTabbedDocumentViewController\(im\)documentViewControllerAtIndex:)                                                             | The `PTDocumentViewController` at the given index.                    |
| [`tabbedDocumentViewController(_:willAdd:)`](https://sdk.apryse.com/api/ios/Protocols/PTTabbedDocumentViewControllerDelegate.html#/c:objc\(pl\)PTTabbedDocumentViewControllerDelegate\(im\)tabbedDocumentViewController:willAddDocumentViewController:) | Access to a `PTDocumentViewController` that is about to be displayed. |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/ios/ui-customization/viewer-configuration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
