---
title: "Customizing menus in iOS PDF viewer | Nutrient SDK"
canonical_url: "https://www.nutrient.io/guides/ios/customizing-the-interface/customizing-menus/"
md_url: "https://www.nutrient.io/guides/ios/customizing-the-interface/customizing-menus.md"
last_updated: "2026-05-23T00:08:18.127Z"
description: "Nutrient uses a modern UIMenu-based menu system for context-sensitive menus when you select annotations or long press on empty space."
---

# Customizing menus on iOS

Nutrient uses a modern [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu)-based menu system for context-sensitive menus when you select annotations or long press on empty space. This guide explains how to work with them and customize them.

## Annotation selection menu

When you select one or more annotations by tapping or right-clicking them on the page, Nutrient will present a menu. This section describes how you can present and customize it yourself in your project.

### Presenting the annotation selection menu

Use [`select(annotations:<wbr>presentMenu:<wbr>animated:)`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfpageview/select(annotations:presentmenu:animated:)) and set `true` for the `presentMenu` parameter to programmatically present the menu for selected annotations:

```swift

pageView.select(annotations: [annotation], presentMenu: true, animated: true)

```

### Customizing the annotation selection menu

Implement the [`pdfViewController(\_:<wbr>menuForAnnotations:<wbr>onPageView:<wbr>appearance:<wbr>suggestedMenu:)`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontrollerdelegate/pdfviewcontroller(_:menuforannotations:onpageview:appearance:suggestedmenu:)) delegate method to customize the annotation selection menu directly:

```swift

func pdfViewController(_ sender: PDFViewController, menuForAnnotations annotations: [Annotation], onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    // Return the customized `suggestedMenu`.
}

```

To insert a custom menu element into the annotation selection menu, append or prepend it to the children of the `suggestedMenu`. The following example demonstrates how to add a custom **Lock** or **Unlock** action:

```swift

func pdfViewController(_ sender: PDFViewController, menuForAnnotations annotations: [Annotation], onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    // Only customize the menu for a single annotation.
    guard annotations.count == 1, let annotation = annotations.first else {
        return suggestedMenu
    }
    // Only add the custom item when the menu appears as a context menu.
    guard appearance ==.contextMenu else {
        return suggestedMenu
    }
    // Prepend either the Unlock or Lock action.
    if annotation.isLocked {
        let unlockAction = UIAction(title: "Unlock", image: UIImage(systemName: "lock.open")) { _ in
            annotation.flags.remove(.locked)
        }
        return suggestedMenu.replacingChildren([unlockAction] + suggestedMenu.children)
    } else {
        let lockAction = UIAction(title: "Lock", image: UIImage(systemName: "lock")) { _ in
            annotation.flags.insert(.locked)
        }
        return suggestedMenu.replacingChildren([lockAction] + suggestedMenu.children)
    }
}

```

Returning a [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) with no children will prevent the annotation selection menu from being presented. See the [Common Customization Techniques](#common-customization-techniques) section to learn more about all the different ways you can customize the suggested [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) object.

We don’t recommend ignoring the suggested menu or returning an empty menu. Doing so may break important functionality such as copying, modifying, and deleting annotations. Certain actions are only possible through the annotation selection menu.

### Customizing choices in the style menu

To customize choices available in the **Style** menu for selected annotations, you don’t need to customize the menu directly. Instead, use [`annotationMenuConfiguration`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/annotationmenuconfiguration) and set the custom closure for one of the following properties:

- [`alphaChoices`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pspdfannotationmenuconfiguration/alphachoices)

- [`colorChoices`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/annotationmenuconfiguration/colorchoices)

- [`fontSizeChoices`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pspdfannotationmenuconfiguration/fontsizechoices)

- [`lineEndChoices`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pspdfannotationmenuconfiguration/lineendchoices)

- [`lineWidthChoices`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pspdfannotationmenuconfiguration/linewidthchoices)

The following example demonstrates how to customize the available color choices for free text annotations but leave the default choices for other annotations:

```swift

let configuration = PDFConfiguration {
    $0.annotationMenuConfiguration = AnnotationMenuConfiguration {
        $0.colorChoices = { property, annotation, pageView, defaultChoices in
            if property ==.color, annotation is FreeTextAnnotation {
                return [.systemRed,.systemGreen]
            } else {
                return defaultChoices
            }
        }
    }
}

```

To learn more about configuring the [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller) using the [`PDFConfiguration`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfconfiguration) object, check out our [Configure PDF View Controllers](https://www.nutrient.io/guides/ios/getting-started/view-controller-configuration.md) guide.

## Annotation creation menu

When you long press or right-click on empty space on a page, Nutrient will present the menu that includes the **Paste** action and tools for creating different types of annotations. This section describes how you can present and customize it yourself in your project.

### Presenting the annotation creation menu

Use the [`tryToShowAnnotationMenu(at:<wbr>in:)`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/documentviewinteractions/trytoshowannotationmenu(at:in:)) method to programmatically present the annotation selection menu at a given location:

```swift

viewController.interactions.tryToShowAnnotationMenu(at: point, in: coordinateSpace)

```

To learn more about working with the user interaction components, check out our [Customize User Interactions](https://www.nutrient.io/guides/ios/customizing-the-interface/handling-user-interactions.md) guide.

### Customizing the annotation creation menu

Implement the [`pdfViewController(\_:<wbr>menuForCreatingAnnotationAt:<wbr>onPageView:<wbr>appearance:<wbr>suggestedMenu:)`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontrollerdelegate/pdfviewcontroller(_:menuforcreatingannotationat:onpageview:appearance:suggestedmenu:)) delegate method to customize the annotation creation menu directly:

```swift

func pdfViewController(_ sender: PDFViewController, menuForCreatingAnnotationAt point: CGPoint, onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    // Return the customized `suggestedMenu`.
}

```

Returning a [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) with no children will prevent the annotation creation menu from being presented. However, to disable the annotation creation menu altogether, it’s recommended to set the [`isCreateAnnotationMenuEnabled`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfconfiguration/iscreateannotationmenuenabled) configuration property to `false`.

See the [Common Customization Techniques](#common-customization-techniques) section to learn more about all the different ways you can customize the suggested [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) object.

### Customizing the tools in the annotation creation menu

To customize which tools are available in the annotation creation menu, you don’t need to customize the menu directly. Instead, use the [`createAnnotationMenuGroups`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfconfiguration/createannotationmenugroups) configuration property.

The following example demonstrates how to limit the tools to include only arrow, ellipse, distance measurement, and rectangular measurement annotations:

```swift

let configuration = PDFConfiguration {
    $0.createAnnotationMenuGroups = [.init(items: [.init(
                type:.line,
                variant:.lineArrow,
                configurationBlock: AnnotationToolConfiguration.ToolItem.lineConfigurationBlock()
            )
        ]),.init(items: [.init(
                type:.line,
                variant:.distanceMeasurement,
                configurationBlock: AnnotationToolConfiguration.ToolItem.measurementConfigurationBlock()
            ),.init(
                type:.square,
                variant:.rectangularAreaMeasurement,
                configurationBlock: AnnotationToolConfiguration.ToolItem.measurementConfigurationBlock()
            )
        ])
    ]
}

```

To learn more about configuring the [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller) using the [`PDFConfiguration`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfconfiguration) object, check out our [Configure PDF View Controllers](https://www.nutrient.io/guides/ios/getting-started/view-controller-configuration.md) guide.

Check out the API reference for [`Annotation.Kind`](https://www.nutrient.io/api/ios/documentation/pspdfkit/annotation/kind) and [`Annotation.ToolVariantID`](https://www.nutrient.io/api/ios/documentation/pspdfkit/annotation/variant-swift.struct/inkpen) to see the list of all supported tools and variants. To learn more about measurement annotations specifically, check out our [Measure Distance and Area in a PDF](https://www.nutrient.io/guides/ios/measurements.md) guide.

## Text selection menu

When you select text by a long press or a right click, Nutrient presents a menu. This section explains how to present and customize this menu in your project.

### Presenting the text selection menu

The text selection menu can only be presented in response to user interaction. Programmatically presenting this menu isn’t possible.

### Customizing the text selection menu

Implement the [`pdfViewController(\_:<wbr>menuForText:<wbr>onPageView:<wbr>appearance:<wbr>suggestedMenu:)`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontrollerdelegate/pdfviewcontroller(_:menufortext:onpageview:appearance:suggestedmenu:)) delegate method to customize the text selection menu directly:

```swift

func pdfViewController(_ sender: PDFViewController, menuForText glyphs: GlyphSequence, onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    // Return the customized `suggestedMenu`.
}

```

Returning a [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) with no children prevents the text selection menu from being displayed. To disable text selection altogether, it’s recommended to set the [`isTextSelectionEnabled`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfconfiguration/istextselectionenabled) configuration property to `false`.

See the [common customization techniques](#common-customization-techniques) section to learn more about customizing the [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) object.

### Customizing the tools in the text selection menu

To customize which tools are available in the text selection menu, use [`contentMenuConfiguration`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/contentmenuconfiguration) and set the custom closure for the [`annotationToolChoices`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/contentmenuconfiguration/annotationtoolchoices) property.

The following example demonstrates how to limit the tools to include only highlight, underline, and redaction annotations:

```swift

let configuration = PDFConfiguration {
    $0.contentMenuConfiguration = ContentMenuConfiguration {
        $0.annotationToolChoices = { glyphs, pageView, appearance, defaultChoices in
            [.highlight,.underline,.redaction]
        }
    }
}

```

To learn more about configuring [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller) using the [`PDFConfiguration`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfconfiguration) object, see the guide on how to [configure PDF view controllers](https://www.nutrient.io/guides/ios/getting-started/view-controller-configuration.md).

## Image selection menu

This section refers to images that are part of the page content. To customize the menu for **image annotations**, see the [Annotation Selection Menu](#annotation-selection-menu) section instead.

When you select an image by a long press or a right click, Nutrient presents a menu. This section explains how to present and customize this menu in your project.

### Presenting the image selection menu

To programmatically present the menu for a selected image, use [`select(image:<wbr>presentMenu:<wbr>animated:)`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfpageview/select(image:presentmenu:animated:)) and set the `presentMenu` parameter to `true`:

```swift

let image = pageView.selectionView.selectedImage
pageView.select(image: image, presentMenu: true, animated: true)

```

### Customizing the image selection menu

Implement the [`pdfViewController(\_:<wbr>menuForImage:<wbr>onPageView:<wbr>appearance:<wbr>suggestedMenu:)`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontrollerdelegate/pdfviewcontroller(_:menuforimage:onpageview:appearance:suggestedmenu:)) delegate method to customize the image selection menu directly:

```swift

func pdfViewController(_ sender: PDFViewController, menuForImage image: ImageInfo, onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    // Return the customized `suggestedMenu`.
}

```

Returning a [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) with no children prevents the image selection menu from being displayed. To disable image selection altogether, set the [`isImageSelectionEnabled`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfconfiguration/isimageselectionenabled) configuration property to `false`.

See the [common customization techniques](#common-customization-techniques) section to learn more about how to customize the [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) object.

## Common customization techniques

This section describes a variety of customization use cases that apply to both annotation selection and annotation creation menus.

Can’t find how to customize the annotation selection or annotation selection menu for your specific use case? [Reach out to us](https://support.nutrient.io/hc/en-us/requests/new) and we’ll be happy to help!

### Filtering the suggested menu elements

Implement one of the [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu)-based delegate methods and modify the `suggestedMenu` parameter to exclude certain default actions or submenus. Keep in mind that you need to search the entire menu tree, and not just the immediate children of the `suggestedMenu`.

The following example demonstrates how to limit the default actions in the annotation selection menu to just **Copy** and **Delete**:

```swift

func pdfViewController(_ sender: PDFViewController, menuForAnnotations annotations: [Annotation], onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    // The `filterAction` function used here is defined below.
    suggestedMenu.filterActions {
        $0 ==.PSPDFKit.copy || $0 ==.PSPDFKit.delete
    }
}

```

Check out the API reference for Nutrient’s [`UIAction.Identifier`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/uikit/uiaction/identifier/pspdfkit) and [`UIMenu.Identifier`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/uikit/uimenu/identifier/pspdfkit) namespaces to see the list of all available identifiers you can use to filter out actions and submenus from the `suggestedMenu`.

Here’s the implementation of the `filterAction` helper method used above:

```swift

extension UIMenu {

    func filterActions(_ predicate: (UIAction.Identifier) -> Bool) -> UIMenu {
        replacingChildren(children.compactMap { element in
            if let action = element as? UIAction {
                if predicate(action.identifier) {
                    return action
                } else {
                    return nil
                }
            } else if let menu = element as? UIMenu {
                // Filter children of submenus recursively.
                return menu.filterActions(predicate)
            } else {
                return element
            }
        })
    }

}

```

### Inserting custom actions

Implement one of the [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu)-based delegate methods, and modify the `suggestedMenu` parameter to include a custom menu element. The following example demonstrates how to insert a **Select All Annotations** action into the annotation creation menu:

```swift

func pdfViewController(_ sender: PDFViewController, menuForCreatingAnnotationAt point: CGPoint, onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    // Only include the action if there are any annotations on the page.
    guard let annotations = pageView.document?.annotations(at: pageView.pageIndex),!annotations.isEmpty else {
        return suggestedMenu
    }
    // Prepend the action to the `suggestedMenu`.
    let selectAllAction = UIAction(title: "Select All Annotations", image: UIImage(systemName: "circle.rectangle.dashed")) { _ in
        pageView.select(annotations: annotations, presentMenu: true, animated: true)
    }
    return suggestedMenu.replacingChildren([selectAllAction] + suggestedMenu.children)
}

```

You can use [`UIAction`](https://developer.apple.com/documentation/uikit/uiaction) to insert closure-based actions, [`UICommand`](https://developer.apple.com/documentation/uikit/uicommand) to insert responder chain actions, and [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) to insert submenus. [`UIDeferredMenuElement`](https://developer.apple.com/documentation/uikit/uideferredmenuelement) is also supported.

### Inserting submenus

Implement one of the [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu)-based delegate methods, and modify the `suggestedMenu` parameter to include a custom submenu. Nutrient will take care of presenting it properly.

### Customizing based on menu appearance

Implement one of the [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu)-based delegate methods, and use the `appearance` parameter to conditionally customize the menu based on whether it appears as a [`.horizontalBar`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/editmenuappearance/horizontalbar) or a [`.contextMenu`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/editmenuappearance/contextmenu).

The following example demonstrates how to conditionally prepend a **Custom** action to the annotation creation menu when it appears as a contextual menu, or if there’s enough space in a horizontal bar:

```swift

func pdfViewController(_ sender: PDFViewController, menuForCreatingAnnotationAt point: CGPoint, onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    // Only include the action if there's space.
    guard appearance ==.contextMenu || pageView.traitCollecton.horizontalSizeClass ==.regular else {
        return suggestedMenu
    }
    // Prepend the action to the `suggestedMenu`.
    let customAction = UIAction(title: "Custom") { _ in
        print("Hello from custom action!")
    }
    return suggestedMenu.replacingChildren([customAction] + suggestedMenu.children)
}

```

### Displaying menu elements as images

Menu elements such as [`UIAction`](https://developer.apple.com/documentation/uikit/uiaction), [`UICommand`](https://developer.apple.com/documentation/uikit/uicommand), and [`UIMenu`](https://developer.apple.com/documentation/uikit/uimenu) will be displayed as images if they have empty titles. You can conditionally make your custom actions and submenus appear as images when a menu appears as a horizontal bar.

Always set the [`accessibilityLabel`](https://developer.apple.com/documentation/objectivec/nsobject/1615181-accessibilitylabel) for menu element images that don’t have titles. This will ensure they’re properly discoverable with VoiceOver.

The following example demonstrates how to append a **More** submenu to the annotation selection menu and conditionally display it as an image:

```swift

func pdfViewController(_ sender: PDFViewController, menuForAnnotations annotations: [Annotation], onPageView pageView: PDFPageView, appearance: EditMenuAppearance, suggestedMenu: UIMenu) -> UIMenu {
    let customAction = UIAction(title: "Custom") { _ in
        print("Hello from custom action!")
    }
    // Add the accessibility label to the image.
    let ellipsisImage = {
        let image = UIImage(systemName: "ellipsis")!
        image.accessibilityLabel = "More"
        return image
    }()
    let moreSubmenu = UIMenu(
        // Skip the title only in `.horizontalBar` appearance.
        title: appearance ==.horizontalBar? "" : "More",
        image: ellipsisImage,
        children: [customAction]
    )
    return suggestedMenu.replacingChildren(suggestedMenu.children + [moreSubmenu])
}

```

The **More** submenu from the example above will be displayed as an image when the annotation selection appears as a horizontal bar, but it’ll retain its title when the menu appears as a contextual menu.![](@/assets/guides/ios/customizing-the-interface/customizing-menus/element-as-image.png)
---

## Related pages

- [Localization: Change languages in our iOS PDF viewer](/guides/ios/features/localization.md)
- [Customizing PDF viewer styling on iOS](/guides/ios/customizing-the-interface/appearance-styling.md)
- [Customizing our iOS PDF viewer](/guides/ios/user-interface.md)
- [Overriding classes in our iOS viewer](/guides/ios/getting-started/overriding-classes.md)
- [Customizing the toolbar in our visionOS PDF viewer](/guides/ios/user-interface/main-toolbar-visionos.md)
- [Editing PDFs in our iOS viewer](/guides/ios/features/document-editor-ui.md)
- [Customize electronic signatures UI on iOS](/guides/ios/signatures/customizing-the-signature-user-interface.md)
- [Customizing the toolbar in our iOS PDF viewer](/guides/ios/user-interface/main-toolbar.md)

