iOS, iPadOS & Mac Catalyst API reference
Generated from the Swift package's sources. For a guided introduction — installing the package, the license key, presenting the editor, customizing it — start with the iOS, iPadOS & Mac Catalyst guide.
Module PDFEditorUI (iOS, iPadOS, Mac Catalyst): 54 public types and 383 members, generated from the SDK's sources at build time, so this page cannot drift from them.
- The editor —
PDFEditorMode,PDFEditorTool,PDFEditorView,PDFEditorViewController - Customization —
SignaturePlacement,PDFEditorLocalization,PDFColor,PDFEditorConfiguration,PDFEditorHandleShape,PDFEditorFont,PDFEditorCustomAction,PDFEditorActionContext,PDFEditorToolbarItem,PDFEditorMenuEntry,PDFEditorAction,PDFEditorStamp,PDFEditorSignatureMethod,PDFEditorHeaderButton,PDFEditorMenuItem,PDFEditorColorScheme,PDFEditorColors,PDFEditorMarkupStyle,PDFEditorInkStyle,PDFEditorToolDefaults,PDFEditorAppearance,PDFSigner.Appearance,PDFEditorLocalization.LayoutDirection - Signing —
SignaturesView,DigitalSignFormModel,DigitalID,PDFSigner,DigitalIDStore,SignatureStatus,PDFSignatureVerifier,DigitalID.SignError - Document API —
PDFDocumentBridgeError,PDFLayer,PDFSearchMatch,PDFFormField,PDFMetadataKey,PDFFontFamily,PDFZOrder,PDFMarkupKind,PDFImageKind,PDFFormFieldKind,PDFTextResult,PDFDocumentError,PDFDocumentEditor,PDFLayer.Kind,PDFLayer.Shape,PDFFormField.Kind - SDK, licensing and callbacks —
PDFEditorLicense,PDFEditorSDK,PDFEditorLicense.Status
The editor
PDFEditorMode
public enum PDFEditorMode: CaseIterableThe mode the editor opens in, chosen by the HOST app when it presents PDFEditorView / PDFEditorViewController. Defaults to .contentEditor. (Public façade over the internal EditorMode.)
contentEditor
case contentEditorviewer
case viewerannotate
case annotatefillSign
case fillSigninsert
case insertdraw
case drawform
case formPDFEditorTool
public enum PDFEditorTool: CaseIterableA specific tool the HOST can pre-arm when it presents PDFEditorView / PDFEditorViewController, INDEPENDENT of initialMode. Every combination is valid and OPTIONAL: • tool alone → the editor opens in the mode that owns the tool (owningMode) and arms it; • tool + initialMode → the tool is armed within the mode the host chose; • initialMode alone → that mode, nothing pre-armed (today's behaviour); • neither → the editor opens exactly as it does now (.contentEditor, nothing armed).
Arming behaves EXACTLY as if the user tapped that tool in the mode toolbar — so .image opens the Photos / Files source picker, .signature opens the signature pad, .addText arms tap-to-place, .highlight arms the highlighter, .shapeRectangle arms rubber-band placement, etc. (Public façade over EditorToolAction.)
addText
case addTextimage
case imagelink
case linkinsertPage
case insertPagemultiSelect
case multiSelecthighlight
case highlightunderline
case underlinestrikeout
case strikeoutsquiggly
case squigglysignature
case signaturestamp
case stampnote
case notedraw
case drawshapeRectangle
case shapeRectangleshapeEllipse
case shapeEllipseshapeLine
case shapeLineshapeArrow
case shapeArrowformTextField
case formTextFieldformCheckBox
case formCheckBoxformRadioButton
case formRadioButtonformListBox
case formListBoxformDropdown
case formDropdownPDFEditorView
public struct PDFEditorView: ViewThe PDF editor as a SwiftUI view. Open a PDF by file URL, edit it, and receive the edited PDF bytes via onSave. Present it however you like (a .fullScreenCover is typical).
.fullScreenCover(isPresented: $editing) {
PDFEditorView(url: pdfURL) { edited in
try? edited.write(to: pdfURL, options: .atomic) // save wherever you want
editing = false
} onCancel: { editing = false }
}Write it atomically, and drop any PDFDocument/PDFView you have open on that same path first. .atomic writes a temp file and renames, so an already-open document keeps its intact inode.
init
public init(
url: URL,
initialMode: PDFEditorMode? = nil,
initialTool: PDFEditorTool? = nil,
configuration: PDFEditorConfiguration = PDFEditorConfiguration(),
onSave: @escaping (Data) -> Void,
onCancel: @escaping () -> Void,
onSharePDF: ((Data) -> Void)? = nil,
onPrint: ((Data) -> Void)? = nil,
onFlattenAndShare: ((Data) -> Void)? = nil,
onDigitallySigned: ((Data) -> Void)? = nil,
onUnsavedChangesChanged: ((Bool) -> Void)? = nil,
onDocumentReady: ((PDFDocumentEditor) -> Void)? = nil,
)- Parameters:
- url: the PDF file to edit. The editor opens on the first page.
- initialMode: the mode the editor opens in. Optional — omit (or
nil) for the default. When ainitialToolis given without a mode, the editor opens in the mode that owns the tool; when neither is given it opens in.contentEditor, exactly as before. - initialTool: a tool to pre-arm on open (Add Text, Image, Link, Highlight, Signature, a shape, …), INDEPENDENT of
initialMode. Optional — omit (ornil) to open with nothing armed. Arming behaves exactly like tapping the tool (e.g..imageopens the source picker,.signaturethe signature pad). - configuration: which modes, tools and ⋮-menu items the editor offers, its colour scheme, the tools' first-use styles, zoom range and haptics. Optional — the default is the editor as it ships. See
PDFEditorConfiguration. - onSave: called with the edited PDF's bytes when the user saves.
- onCancel: called when the user closes the editor without saving.
- onSharePDF: if provided, the ⋮ menu's Share PDF hands back the edited PDF bytes instead of presenting the system share sheet — intercept it for a paywall, custom share UI, upload, etc.
- onPrint: if provided, the ⋮ menu's Print hands back the edited PDF bytes instead of opening the system print panel.
- onFlattenAndShare: if provided, the ⋮ menu's Flatten & Share hands back the FLATTENED PDF bytes (form fields baked into page content) instead of presenting the system share sheet. Only shown for documents that contain a form.
When
nil, the editor falls back to presenting the signed PDF in the system share sheet (and logs a note), so signatures are never silently lost. - onUnsavedChangesChanged: called with
trueas soon as the document has edits that aren't saved, andfalseonce they are. On Mac Catalyst you should track this: the window's red close button is an AppKit affordance that UIKit scene APIs cannot veto, so the editor cannot put up its own "unsaved changes" prompt there — closing the window would discard the edits silently. Use this to block or confirm termination in your app (or to auto-save). - onDocumentReady: called once, when the document is open, with a
PDFDocumentEditorfor it — read every layer, change text, styles and geometry, add and remove layers, fill forms, all from code. Its changes show in the editor at once and the user can undo them. Use it on the main thread.
body
public var body: some ViewPDFEditorViewController
public final class PDFEditorViewController: UIHostingController<PDFEditorView>The PDF editor as a UIKit view controller (a UIHostingController around PDFEditorView). Present it from any view controller; it defaults to full-screen presentation.
let editor = PDFEditorViewController(url: pdfURL,
onSave: { data in /* save */ }, onCancel: { [weak self] in self?.dismiss(animated: true) })
present(editor, animated: true)init
public init(
url: URL,
initialMode: PDFEditorMode? = nil,
initialTool: PDFEditorTool? = nil,
configuration: PDFEditorConfiguration = PDFEditorConfiguration(),
onSave: @escaping (Data) -> Void,
onCancel: @escaping () -> Void,
onSharePDF: ((Data) -> Void)? = nil,
onPrint: ((Data) -> Void)? = nil,
onFlattenAndShare: ((Data) -> Void)? = nil,
onDigitallySigned: ((Data) -> Void)? = nil,
onUnsavedChangesChanged: ((Bool) -> Void)? = nil,
onDocumentReady: ((PDFDocumentEditor) -> Void)? = nil,
)- Parameters:
- url: the PDF file to edit. The editor opens on the first page.
- configuration: modes, tools, ⋮-menu items, colour scheme, tool styles, zoom, haptics — see
PDFEditorConfiguration. Optional. - onSave: called with the edited PDF's bytes when the user saves.
- onCancel: called when the user closes the editor without saving.
- onSharePDF / onPrint / onFlattenAndShare: optional interceptors for the matching ⋮-menu export actions — each hands back the PDF bytes instead of presenting the system sheet (see
PDFEditorView). - onDigitallySigned: if provided, called with the signed PDF's bytes after the user digitally signs; when unset the signed document is handed to the system share sheet instead (see
PDFEditorView). - onDocumentReady: the open document as a
PDFDocumentEditor, for changes from code (seePDFEditorView).
present
public override func present(
_ viewControllerToPresent: UIViewController,
animated flag: Bool,
completion: (() -> Void)? = nil,
)A presented controller takes its style from the WINDOW, not from the controller that presented it, so the override above reached the editor but not its sheets: a host that pinned .dark got a dark editor with a light Tools sheet, font picker and signature pad. SwiftUI presents those through this controller, so the pinned style is handed on here.
Customization
SignaturePlacement
public enum SignaturePlacement: String, CaseIterable, Identifiable, SendableWhere the visible signature box is drawn on the current page.
bottomRight
case bottomRight = "Bottom Right", bottomLeft = "Bottom Left"topRight
case topRight = "Top Right", topLeft = "Top Left"invisible
case invisible = "Invisible"title
public var title: StringThe placement's name in the editor's language (the raw value is the stable English id).
id
public var id: Stringinit
public init?(name: String)The cross-platform name (bottomRight, bottomLeft, topRight, topLeft, invisible), as the Flutter / React Native options and Android's PdfSignaturePlacement spell it. Case-insensitive.
PDFEditorLocalization
public struct PDFEditorLocalizationHow the editor is translated. PDFEditorConfiguration.localization.
language
public var language: String?The editor's language as a BCP-47 code ("hi", "ar", "pt-BR"). Picks the .lproj table, the date format of stamps, and — for right-to-left languages — the layout direction. nil = the app's current language.
strings
public var strings: [String: String] = [:]Key → text. Placeholders {1}, {2} … are filled in by the editor.
provider
public var provider: ((_ key: String, _ english: String) -> String?)?Asked for every key strings doesn't have; return nil to fall through.
bundle
public var bundle: Bundle?Where to look for <language>.lproj/<tableName>.strings. nil = the app's main bundle.
tableName
public var tableName = "PDFEditor"layoutDirection
public var layoutDirection: LayoutDirection = .automaticLeft-to-right or right-to-left chrome.
init
public init(
language: String? = nil,
strings: [String: String] = [:],
provider: ((_ key: String, _ english: String) -> String?)? = nil,
)PDFColor
public struct PDFColor: Hashable, SendableA colour as the engine stores it: 8-bit RGBA.
red
public var red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8init
public init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8 = 255)init
public init(rgba: UInt32)0xRRGGBBAA.
init
public init(_ color: UIColor)rgba
public var rgba: UInt32uiColor
public var uiColor: UIColorblack
public static let black = PDFColor(rgba: 0x000000FF)white
public static let white = PDFColor(rgba: 0xFFFFFFFF)clear
public static let clear = PDFColor(rgba: 0)PDFEditorConfiguration
public struct PDFEditorConfigurationOne editor's customisation. Every property has the SDK's own behaviour as its default, so PDFEditorConfiguration() is exactly the editor you get without passing one.
modes
public var modes: [PDFEditorMode] = []The modes the Tools sheet offers, in the order given. Duplicates are dropped. An empty list means every mode. A mode whose tools are ALL hidden (see hiddenTools) is dropped too, except .viewer, which has no tools. With one mode left, the header shows its name without the mode picker.
initialMode must be one of these; otherwise the editor opens in the first one. Form Editor stays unavailable on Mac Catalyst whatever this says.
hiddenTools
public var hiddenTools: Set<PDFEditorTool> = []Tools removed from every mode's toolbar. .addText appears in several modes and is hidden in all of them. An initialTool that is hidden is not armed.
hiddenMenuItems
public var hiddenMenuItems: Set<PDFEditorMenuItem> = []Items removed from the ⋮ menu. Items the document can't use (Flatten & Share without a form) are hidden regardless.
colorScheme
public var colorScheme: PDFEditorColorScheme = .systemLight, dark, or follow the system (default). Applies to the editor's own presentation.
toolDefaults
public var toolDefaults = PDFEditorToolDefaults()The style each tool starts with the first time it is used. Once the user picks a colour or opacity, the editor remembers their choice on this device and that wins, exactly as it does today.
zoomRange
public var zoomRange: ClosedRange<CGFloat> = PDFEditorConfiguration.supportedZoomRangeThe page zoom range, where 1 is the page fitted to the screen. Clamped to what the editor renders crisply (50 %…300 %) and always widened to include 1, so this can narrow the range (1...1 turns pinch-zoom off) but not widen it.
haptics
public var haptics: Bool = trueHaptic feedback on taps, snaps and alignment guides. Default on.
showsUsageHints
public var showsUsageHints: Bool = trueDefault on.
interfaceFontFamily
public var interfaceFontFamily: String?The font family for the editor's own text — toolbar labels, the header, sheets, panels — e.g. "Avenir Next" or a family your app bundles (list its files under UIAppFonts). Sizes stay the editor's, and weights come from the family's own faces. nil (the default) is the system font. A family the app can't load is ignored (and logged). SF Symbols, system menus, alerts and the keyboard keep the system font; the document's own text is never set in it.
fonts
public var fonts: [PDFEditorFont] = []Fonts of your own for the DOCUMENT's text, listed first in the text font picker under fontsTitle. Each must be a TrueType/OpenType file with ordinary outlines (the same test an imported font passes); one that isn't is skipped and logged. Applying one embeds it in the PDF, like any other font the user picks.
fontsTitle
public var fontsTitle = "Featured"The picker section fonts appear under.
showsStandardFonts
public var showsStandardFonts = trueThe picker's other sections: the standard PDF fonts (Helvetica, Times and Courier, which every PDF reader has, so choosing one embeds nothing), the PDF's own embedded fonts, the device's fonts, and the fonts the user imported (with the "+" that imports one). Hide them to limit text to your fonts.
showsDocumentFonts
public var showsDocumentFonts = trueshowsDeviceFonts
public var showsDeviceFonts = trueallowsFontImport
public var allowsFontImport = truenewTextFont
public var newTextFont: PDFEditorFont?A font of yours for NEW text: a box the user places is set in it. Its size and colour still follow the text around it, as they always do. Validated like fonts (one that isn't usable is ignored and logged) and embedded when the first box is placed. nil (the default) matches the page's own text.
selectionColor
public var selectionColor: UIColor?The colour of the selection: the box around a selected layer, its handles' rings, the rotation knob, the text caret, the text-selection band and its grab handles, and the guide that marks alignment with the page. Always drawn opaque. A dynamic colour follows the editor's light/dark scheme. nil = the accent (colors.accent), else system blue.
handleFillColor
public var handleFillColor: UIColor?The handles' (and the rotation knob's) fill. nil = white.
handleShape
public var handleShape: PDFEditorHandleShape = .roundedSquarehandleScale
public var handleScale: CGFloat = 1Handle and knob size, 0.75…1.5 (clamped). A mouse's or trackpad's reach for them follows the size; a finger's is already wider than the largest handle, and how small a layer can be resized doesn't change.
selectionBorderWidth
public var selectionBorderWidth: CGFloat = 1.5The selection box's and the handles' outline, in points: 1…3 (clamped).
rotateIcon
public var rotateIcon: UIImage?The glyph inside the rotation knob, drawn as a template: its shape, filled with selectionColor. A single-colour image with a transparent background; it's fitted into the knob. nil = the built-in arrow.
searchHighlightColor
public var searchHighlightColor: UIColor?The wash over every search match, and over the current one (with a ring). Only the colour is used: the translucency is the editor's, so the text under a highlight always reads. nil = yellow / orange.
searchCurrentHighlightColor
public var searchCurrentHighlightColor: UIColor?colors
public var colors = PDFEditorColors()THE EDITOR'S OWN COLOURS — its accent, the canvas around the pages, the toolbars and panels, and what is drawn on them. Each one left nil keeps the editor's own, so a host can change just the accent without taking on the rest.
Set a toolbarBackground and leave toolbarForeground nil, and the editor picks white or near-black ink for it by its luminance, so a brand colour is never paired with unreadable labels. The ⋮ menu and the system sheets (share, print, photo picker) are drawn by iOS and keep the system's colours; they take the accent.
markupColors
public var markupColors: [UIColor] = []The Annotate colour row (highlight, underline, strikethrough, squiggly), left to right. Empty = the editor's own.
inkColors
public var inkColors: [UIColor] = []The Draw ink bar's colours on Mac Catalyst. Empty = the editor's own.
signatureColors
public var signatureColors: [UIColor] = []The signature pad's ink colours; the first is the default ink. Empty = the editor's own.
stamps
public var stamps: [PDFEditorStamp] = []The Stamp tool's presets, in order. Empty = the editor's own (APPROVED, DRAFT, CONFIDENTIAL, REJECTED, FINAL and today's date). .date(color:) is a stamp that reads the day it's placed.
allowsCustomStamp
public var allowsCustomStamp = trueThe stamp picker's Custom Photo… button.
fontSizes
public var fontSizes: [Int] = []The font-size list, in points (1…400, duplicates dropped, sorted). Empty = the editor's own 8…144.
signatureMethods
public var signatureMethods: [PDFEditorSignatureMethod] = []The signature pad's tabs, in order. Empty = all of them. .eSign shows only when digital signing is wired, and a list that leaves nothing falls back to .draw.
signaturePlacement
public var signaturePlacement: SignaturePlacement = .bottomRightWhere the e-Sign tab's Placement picker starts (the user can still change it). Default .bottomRight.
showsUndoRedo
public var showsUndoRedo = trueThe floating pills along the bottom: undo / redo, the page navigator, and zoom.
showsPageNavigator
public var showsPageNavigator = trueshowsZoomControls
public var showsZoomControls = truelocalization
public var localization = PDFEditorLocalization()THE EDITOR'S LANGUAGE — every word it shows, by key: a dictionary, a lookup function, or the host's own <language>.lproj/PDFEditor.strings. Untranslated keys stay English; right-to-left languages flip the chrome. The key list is docs/localization/strings.json. The names below (toolTitles…) win over it.
toolTitles
public var toolTitles: [PDFEditorTool: String] = [:]Your own names for tools, e.g. [.highlight: "Mark"]. A tool that appears in several modes (.addText) takes the name everywhere. Empty strings are ignored.
toolIcons
public var toolIcons: [PDFEditorTool: UIImage] = [:]Your own icons for tools. Drawn as a template (tinted like the built-in glyphs, blue when armed) at 20 pt, so use a single-colour image with a transparent background.
modeTitles
public var modeTitles: [PDFEditorMode: String] = [:]Your own names for modes: the header and the Tools sheet.
modeIcons
public var modeIcons: [PDFEditorMode: UIImage] = [:]Your own icons for modes in the Tools sheet, drawn as a template on the mode's coloured tile.
menuItemTitles
public var menuItemTitles: [PDFEditorMenuItem: String] = [:]Your own names and icons for the ⋮ menu's items.
menuItemIcons
public var menuItemIcons: [PDFEditorMenuItem: UIImage] = [:]headerIcons
public var headerIcons: [PDFEditorHeaderButton: UIImage] = [:]Your own icons for the header's buttons, drawn as a template.
actionTitles
public var actionTitles: [PDFEditorAction: String] = [:]Your own names for the SUB-TOOLS: the controls that appear once something is selected (the property bar's Edit, Color, Font, Crop, Cut, Delete…), the menu over the selection (Edit · Duplicate · Delete), and the page panel's page actions. A name applies wherever that action appears. Empty names are ignored.
actionIcons
public var actionIcons: [PDFEditorAction: UIImage] = [:]Your own icons for sub-tools, drawn as templates like toolIcons. Colour wells, steppers and the size button show a value rather than an icon, so an icon there is ignored.
hiddenActions
public var hiddenActions: Set<PDFEditorAction> = []Sub-tools removed wherever they appear. Nothing replaces an action you hide.
actionOrder
public var actionOrder: [PDFEditorAction] = []Listed sub-tools first, in this order, in every bar and menu that has them; the rest keep the editor's order. The bar's dividers follow the new order.
customTools
public var customTools: [PDFEditorMode: [PDFEditorCustomAction]] = [:]A tap commits any edit in progress and calls the handler; the editor does nothing else. A mode with only custom tools still shows its toolbar — even .viewer.
customMenuItems
public var customMenuItems: [PDFEditorCustomAction] = []⋮ menu items of your own, after the built-in items (reorder with menuOrder).
toolOrder
public var toolOrder: [PDFEditorMode: [PDFEditorToolbarItem]] = [:]The order of a mode's toolbar. Listed items come first, in this order; everything else the mode has follows in its usual order, so ordering never hides a tool (that's hiddenTools). A tool the mode doesn't carry is ignored: tools can be reordered within a mode, not moved to another.
config.toolOrder[.fillSign] = [.custom("approve"), .tool(.signature)]menuOrder
public var menuOrder: [PDFEditorMenuEntry] = []The order of the ⋮ menu, with the same rule: listed items first, the rest after in the usual order.
supportedZoomRange
public static let supportedZoomRange: ClosedRange<CGFloat> = 0.5...3The widest zoom range the editor supports.
init
public init()PDFEditorHandleShape
public enum PDFEditorHandleShapeThe shape of the selection handles.
roundedSquare
case roundedSquarecircle
case circlesquare
case squarePDFEditorFont
public struct PDFEditorFontA font file of the host's, for PDFEditorConfiguration.fonts.
init
public init(url: URL)A font file — typically one in your app bundle (Bundle.main.url(forResource: "Brand", withExtension: "ttf")).
init
public init(data: Data)Font bytes you already hold (downloaded, decrypted, generated).
PDFEditorCustomAction
public struct PDFEditorCustomActionA button of the host's own, in a mode's toolbar or the ⋮ menu.
id
public var id: StringUnique among your custom actions; toolOrder / menuOrder refer to it by this.
title
public var title: Stringimage
public var image: UIImage?Drawn as a template at 20 pt. nil shows a generic glyph in the toolbar and none in the menu.
handler
public var handler: @MainActor (PDFEditorActionContext) -> VoidCalled on the main thread, after any edit in progress was committed.
init
public init(
id: String,
title: String,
image: UIImage? = nil,
handler: @escaping @MainActor (PDFEditorActionContext) -> Void,
)PDFEditorActionContext
public struct PDFEditorActionContextWhat a custom action's handler can see of the document.
pageIndex
public let pageIndex: IntThe page on screen, 0-based, and the page count.
pageCount
public let pageCount: IntcurrentPDF
public func currentPDF() -> Data?The document as it stands, every edit included, as PDF bytes. Nothing is saved and onSave is not called; this is a copy. nil only if the export failed.
PDFEditorToolbarItem
public enum PDFEditorToolbarItem: HashableAn entry in toolOrder: a built-in tool, or one of your customTools by id.
tool
case tool(PDFEditorTool)custom
case custom(String)PDFEditorMenuEntry
public enum PDFEditorMenuEntry: HashableAn entry in menuOrder: a built-in ⋮ item, or one of your customMenuItems by id.
item
case item(PDFEditorMenuItem)custom
case custom(String)PDFEditorAction
public enum PDFEditorAction: String, CaseIterable, HashableA sub-tool: a control that appears once something is selected — in the property bar that replaces the mode toolbar, or in the menu over the selection — or on a page in the page panel. Customise them with PDFEditorConfiguration.actionTitles, actionIcons, hiddenActions and actionOrder.
multiSelect
case multiSelectMulti: add to / remove from a multi-layer selection.
editText
case editTextEdit a text layer's words (bar and menu).
textColor
case textColorA text layer's colour well.
font
case fontThe font picker.
textStyle
case textStyleBold · Italic · Underline · Strikethrough (one group; its title is the caption under it).
fontSize
case fontSizeThe font-size button.
opacity
case opacityThe opacity stepper.
strokeColor
case strokeColorA shape's outline colour well.
fillColor
case fillColorA shape's or path's fill colour well.
strokeWidth
case strokeWidthA shape's outline width stepper.
editNote
case editNoteEdit a sticky note (bar and menu).
noteColor
case noteColorA sticky note's card colour well.
resign
case resignDraw a placed signature again (bar and menu).
replaceImage
case replaceImageReplace an image (bar and menu).
crop
case cropCrop an image or signature.
playSound
case playSoundPlay / pause / replay a sound note.
link
case linkLink a layer to a URL or page.
cut
case cutcopy
case copyduplicate
case duplicateDuplicate a layer or form field (menu).
delete
case deleteDelete a layer or form field (bar and menu).
formFill
case formFillA form field's menu: fill it in ("Edit Text", "Toggle" or "Choose…", by the field's kind).
formOptions
case formOptionsA list or dropdown field's Options.
formRadioGroup
case formRadioGroupA radio button's Group.
formColors
case formColorsA form field's Color submenu (fill, border, text).
formBorderWidth
case formBorderWidthA form field's Border Width submenu.
paste
case pastePaste, on the empty page's menu.
rotatePageLeft
case rotatePageLeftThe page panel's actions on a page.
rotatePageRight
case rotatePageRightduplicatePage
case duplicatePageinsertBlankPage
case insertBlankPagedeletePage
case deletePageinit
public init?(name: String)The action for a cross-platform name — the same spelling as the case (editText, rotatePageLeft, …).
PDFEditorStamp
public struct PDFEditorStampA rubber stamp for PDFEditorConfiguration.stamps: its text and its ink.
text
public var text: Stringcolor
public var color: UIColorisDate
public var isDate: BoolReads the date it's placed instead of text.
init
public init(_ text: String, color: UIColor)date
public static func date(color: UIColor) -> PDFEditorStampToday's date, formatted for the device's locale when the stamp is placed.
PDFEditorSignatureMethod
public enum PDFEditorSignatureMethod: String, CaseIterableThe signature pad's tabs, for PDFEditorConfiguration.signatureMethods.
draw
case draw, type, image, eSignPDFEditorHeaderButton
public enum PDFEditorHeaderButton: CaseIterableThe header's buttons.
back
case backpages
case pagesmore
case moredone
case donePDFEditorMenuItem
public enum PDFEditorMenuItem: CaseIterableThe ⋮ (More) menu's items.
search
case searchmanagePages
case managePagessharePDF
case sharePDFprint
case printflattenAndShare
case flattenAndShareresetForm
case resetFormresetToOriginal
case resetToOriginalPDFEditorColorScheme
public enum PDFEditorColorSchemeThe editor's colour scheme.
system
case systemlight
case lightdark
case darkPDFEditorColors
public struct PDFEditorColorsThe editor's colours, for PDFEditorConfiguration.colors. nil keeps the editor's own.
accent
public var accent: UIColor?Buttons, the armed tool, Done, switches, the current page — anything that says "this one".
onAccent
public var onAccent: UIColor?Text and glyphs drawn ON the accent (Done's check, the open pages button). Default white.
canvasBackground
public var canvasBackground: UIColor?Behind and around the pages.
toolbarBackground
public var toolbarBackground: UIColor?The header, the mode toolbar, the property bars and the floating pills. Replaces their frosted material (and, on iOS 26, their Liquid Glass) with this solid colour.
toolbarForeground
public var toolbarForeground: UIColor?Icons and labels on those bars, and the primary text in the editor's own panels.
secondaryForeground
public var secondaryForeground: UIColor?Captions, hints, placeholders, inactive labels. Default: toolbarForeground at reduced strength.
panelBackground
public var panelBackground: UIColor?The editor's own sheets (Tools, fonts, pages). Default: toolbarBackground, or the system's.
destructive
public var destructive: UIColor?Delete and other destructive actions.
init
public init(
accent: UIColor? = nil,
onAccent: UIColor? = nil,
canvasBackground: UIColor? = nil,
toolbarBackground: UIColor? = nil,
toolbarForeground: UIColor? = nil,
secondaryForeground: UIColor? = nil,
panelBackground: UIColor? = nil,
destructive: UIColor? = nil,
)PDFEditorMarkupStyle
public struct PDFEditorMarkupStyleA text-markup tool's first-use style. opacity is clamped to 0.1…1 (the slider's range).
color
public var color: UIColoropacity
public var opacity: CGFloatinit
public init(color: UIColor, opacity: CGFloat = 1)PDFEditorInkStyle
public struct PDFEditorInkStylewidth is clamped to 1…30 points, opacity to 0.1…1. width is clamped to 1…30 and opacity to 0.1…1.
color
public var color: UIColorwidth
public var width: CGFloatopacity
public var opacity: CGFloatinit
public init(color: UIColor, width: CGFloat = 5, opacity: CGFloat = 1)PDFEditorToolDefaults
public struct PDFEditorToolDefaultsThe defaults are the editor's own.
highlight
public var highlight = PDFEditorMarkupStyle(
color: warmYellow,
opacity: 0.5,
)A see-through wash, so the text reads through it.
underline
public var underline = PDFEditorMarkupStyle(color: warmYellow)strikeout
public var strikeout = PDFEditorMarkupStyle(color: warmYellow)squiggly
public var squiggly = PDFEditorMarkupStyle(color: warmYellow)ink
public var ink = PDFEditorInkStyle(color: .black)init
public init()PDFEditorAppearance
public enum PDFEditorAppearancePublic appearance knobs the host app can tune from OUTSIDE the SDK (before or while an editor is shown).
dockScale
@MainActor public static var dockScale: CGFloat = 0Size multiplier for the floating tool DOCK (its icons, labels, chips, paddings — the whole capsule grows/shrinks, and its snap positioning follows because the metrics feed the layout, not a render transform). 0 = AUTOMATIC: 1.0 on iPhone, 1.35 on iPad (the dock reads small on the larger iPad screen). Set any value > 0 to force a specific scale for testing/tuning; clamped to 0.5…3.0.
PDFEditorAppearance.dockScale = 1.6 // bigger dock on iPad for testingPDFSigner.Appearance
public struct Appearancereason
public var reason: String?location
public var location: String?page
public var page: Int?Page index for a VISIBLE signature (draws the box); nil = invisible.
rect
public var rect: CGRect?Rect in PDF points (x, y from the page's bottom-left, width, height).
init
public init(
reason: String? = nil,
location: String? = nil,
page: Int? = nil,
rect: CGRect? = nil,
)PDFEditorLocalization.LayoutDirection
public enum LayoutDirection: SendableSigning
SignaturesView
public struct SignaturesView: ViewonClose
public var onClose: (() -> Void)?init
public init(pdf: Data, onClose: (() -> Void)? = nil)body
public var body: some ViewDigitalSignFormModel
public final class DigitalSignFormModel: ObservableObjectname
@Published public var name: Stringorg
@Published public var org = ""email
@Published public var email = ""reason
@Published public var reason = peL(
"i_approve_this_document",
"I approve this document",
)location
@Published public var location = ""placement
@Published public var placement: SignaturePlacement = .bottomRightmakeNew
@Published public var makeNew: BoolexistingSignerName
public let existingSignerName: String?onCanSignChanged
public var onCanSignChanged: (() -> Void)?Fired whenever canSign might have changed, so the host (pad) can enable/disable Done.
init
public init(
existingSignerName: String?,
placement: SignaturePlacement = .bottomRight,
)canSign
public var canSign: BoolDigitalID
public struct DigitalIDA signing identity: an RSA private key plus its self-signed X.509 certificate (DER).
privateKey
public let privateKey: SecKeycertificateDER
public let certificateDER: [UInt8]createSelfSigned
public static func createSelfSigned(
commonName: String,
organization: String? = nil,
email: String? = nil,
validDays: Int = 3650,
permanentTag: String? = nil,
) throws -> DigitalIDCreate a fresh self-signed identity (ComPDFKit's "create a new Digital ID"). commonName is the signer shown in the signature; org/email are optional.
detachedCMS
public func detachedCMS(
messageDigest: [UInt8],
signingTime: Date,
) throws -> [UInt8]Build the detached PKCS#7 CMS over a message digest (SHA-256, 32 bytes) that the engine supplies.
PDFSigner
public enum PDFSignersign
public static func sign(
pdf: Data,
with id: DigitalID,
signerName: String,
appearance: Appearance = Appearance(),
) throws -> DataSign pdf with id, returning the signed document. signerName is what the appearance shows.
DigitalIDStore
public final class DigitalIDStore: @unchecked SendableStores ONE self-signed Digital ID across launches — the private key in the Keychain, the certificate and its DER sub-pieces in UserDefaults — so "Sign" reuses the same identity instead of minting a new cert each time (ComPDFKit's "manage Digital IDs", minimal single-ID form). Lives in this file for access to DigitalID's internal members.
shared
public static let shared = DigitalIDStore()hasID
public var hasID: BoolsignerName
public var signerName: String?current
public func current() -> DigitalID?The stored identity, or nil if none has been created.
create
public func create(
commonName: String,
organization: String? = nil,
email: String? = nil,
) throws -> DigitalIDloadOrCreate
public func loadOrCreate(
commonName: String,
organization: String? = nil,
email: String? = nil,
) throws -> DigitalIDReuse the stored ID, or create one from the given details if none exists.
reset
public func reset()SignatureStatus
public struct SignatureStatus: Identifiable, SendableResult for one signature in a document.
id
public let id: IntsignerName
public let signerName: StringsigningTime
public let signingTime: Stringreason
public let reason: StringisValid
public let isValid: BoolcoversWholeDocument
public let coversWholeDocument: Boolsummary
public let summary: StringcertificationLevel
public let certificationLevel: IntcertificationSummary
public var certificationSummary: String?Human description of the certification, or nil for an ordinary approval signature.
PDFSignatureVerifier
public enum PDFSignatureVerifierverify
public static func verify(pdf: Data) -> [SignatureStatus]DigitalID.SignError
public enum SignError: ErrorDocument API
PDFDocumentBridgeError
public struct PDFDocumentBridgeError: Error, EquatableWhy a bridged document call failed.
code
public let code: Stringmessage
public let message: StringPDFLayer
public struct PDFLayer: Identifiable, Hashable, SendableOne layer of a page, read as data. Geometry is in page points with the origin at the page's top-left. id addresses the layer in every call that changes it, and keeps naming it while other layers change.
page
public let page: Intid
public let id: Intkind
public let kind: Kindframe
public let frame: CGRectrotation
public let rotation: DoubleDegrees, clockwise as seen.
opacity
public let opacity: DoublezIndex
public let zIndex: IntStacking rank on the page: 0 is the bottom layer.
link
public let link: String?text
public let text: String?fontName
public let fontName: String?fontSize
public let fontSize: Double?isBold
public let isBold: BoolisItalic
public let isItalic: BoolisUnderlined
public let isUnderlined: BoolisStruckThrough
public let isStruckThrough: BoolisFontEmbedded
public let isFontEmbedded: BoolisSymbolic
public let isSymbolic: BoolSet entirely in symbol fonts — an ornament or a check box drawn as letters. Not language: leave it out of any text processing (rewriting, spell checking, search).
textColor
public let textColor: PDFColor?highlightColor
public let highlightColor: PDFColor?pixelSize
public let pixelSize: CGSize?note
public let note: String?noteColor
public let noteColor: PDFColor?noteTextColor
public let noteTextColor: PDFColor?shape
public let shape: Shape?fillColor
public let fillColor: PDFColor?strokeColor
public let strokeColor: PDFColor?strokeWidth
public let strokeWidth: Double?PDFSearchMatch
public struct PDFSearchMatch: Hashable, Sendablepage
public let page: Intrects
public let rects: [CGRect]PDFFormField
public struct PDFFormField: Hashable, SendableA form field of the document.
name
public let name: Stringkind
public let kind: Kindpage
public let page: Intframe
public let frame: CGRectvalue
public let value: StringisChecked
public let isChecked: Bool?exportValue
public let exportValue: String?options
public let options: [String]isReadOnly
public let isReadOnly: BoolPDFMetadataKey
public enum PDFMetadataKey: String, Sendable, CaseIterabletitle
case title = "Title", author = "Author", subject = "Subject", keywords = "Keywords"creator
case creator = "Creator", producer = "Producer"PDFFontFamily
public enum PDFFontFamily: Int32, SendableThe built-in families every PDF reader has.
PDFZOrder
public enum PDFZOrder: Int32, SendablePDFMarkupKind
public enum PDFMarkupKind: Int32, SendablePDFImageKind
public enum PDFImageKind: Int32, SendableWhat an image layer is to the editor: a signature, a hand drawing and a stamp are images it knows by kind.
PDFFormFieldKind
public enum PDFFormFieldKind: Int32, SendablePDFTextResult
public enum PDFTextResult: SendableHow a text replacement went.
replaced
case replacedReplaced, and it fits where the old text was.
overflow
case overflowReplaced, but taller than the old text (it may run into what is below it).
PDFDocumentError
public enum PDFDocumentError: Error, Equatable, SendablecannotOpen
case cannotOpenThe data is not a PDF this engine can open (or the password is wrong).
notFound
case notFoundNo layer, page or field by that address (it may have been deleted — read the layers again).
unsupportedGlyphs
case unsupportedGlyphsNo font can draw some of the characters; NOTHING was changed. Give the editor a font that can.
failed
case failed(String)The engine refused the change (wrong kind of layer, bad value, …).
PDFDocumentEditor
public final class PDFDocumentEditorperform
public func perform(
_ op: String,
_ args: [String: Any] = [:],
) throws -> Any?Run one document operation for a binding. See the file header for the conventions.
bridgeOpen
public static func bridgeOpen(
_ data: Data,
password: String?,
) throws -> PDFDocumentEditorOpen a document for a binding: PDFDocumentEditor(data:password:) with bridge errors.
init
public init(data: Data, password: String? = nil) throwsOpen a PDF headless (no UI).
init
public convenience init(url: URL, password: String? = nil) throwsOpen a PDF file headless (no UI).
pageCount
public var pageCount: IntpageSize
public func pageSize(_ page: Int) throws -> CGSizeThe page's size in points (as displayed, i.e. after its rotation).
save
public func save() throws -> DataThe edited PDF.
metadata
public func metadata(_ key: PDFMetadataKey) -> StringsetMetadata
public func setMetadata(_ key: PDFMetadataKey, _ value: String)Written into the file save() produces.
text
public func text(page: Int) -> StringThe page's plain text.
search
public func search(
_ query: String,
caseSensitive: Bool = false,
) -> [PDFSearchMatch]Every match of query in the document.
renderPage
public func renderPage(_ page: Int, size: CGSize) -> UIImage?The page drawn into an image size pixels big (a thumbnail, a preview, a server-side render).
canUndo
public var canUndo: BoolcanRedo
public var canRedo: Boolundo
@discardableResult public func undo() -> BoolUndo the last change, the user's or this API's. A layer that comes back gets a NEW id — read the layers again.
redo
@discardableResult public func redo() -> BoolinsertBlankPage
public func insertBlankPage(at index: Int, size: CGSize = .zero) throwsInsert a blank page at index (a zero size takes the neighbouring page's).
deletePage
public func deletePage(_ index: Int) throwsmovePage
public func movePage(from: Int, to: Int) throwsduplicatePage
public func duplicatePage(_ index: Int) throwsrotatePage
public func rotatePage(_ index: Int, clockwise: Bool = true) throwsimportPages
public func importPages(
from data: Data,
password: String? = nil,
pages: [Int]? = nil,
at index: Int? = nil,
) throwsCopy pages (all when nil) of another PDF into this one at index (nil = the end). This starts the undo history afresh, as a flatten does, and layer ids must be read again.
extractPages
public func extractPages(_ pages: [Int]) throws -> Datapages of this document as a new PDF.
layers
public func layers(page: Int) -> [PDFLayer]Every layer of the page, in reading order (top to bottom, then left to right) for a page read the first time.
textBlocks
public func textBlocks(page: Int) -> [PDFLayer]layer
public func layer(_ layer: PDFLayer) throws -> PDFLayerThe layer as it is now.
image
public func image(of layer: PDFLayer) -> UIImage?The picture of an image layer, at its own pixel size.
sound
public func sound(of layer: PDFLayer) -> Data?The audio of a sound layer.
setText
public func setText(
_ layer: PDFLayer,
_ text: String,
shrinkToFit: Bool = false,
) throws -> PDFTextResultReplace a text layer's text, keeping its font, size, colour and position. A paragraph re-wraps at its own width; a single line may grow to the page margin. shrinkToFit lowers the size (to half at most) until the text is no taller than before. Any script works: the system's fonts fill in what the layer's font lacks.
setFontSize
public func setFontSize(_ layer: PDFLayer, _ points: Double) throwssetFont
public func setFont(
_ layer: PDFLayer,
family: PDFFontFamily,
bold: Bool = false,
italic: Bool = false,
) throwssetFont
public func setFont(_ layer: PDFLayer, data: Data, name: String) throwsEmbed a font of your own (TTF/OTF bytes) and set the layer in it.
setTextStyle
public func setTextStyle(
_ layer: PDFLayer,
bold: Bool? = nil,
italic: Bool? = nil,
) throwsBold / italic of the current family; nil leaves that one as it is.
setUnderline
public func setUnderline(_ layer: PDFLayer, _ on: Bool) throwssetStrikethrough
public func setStrikethrough(_ layer: PDFLayer, _ on: Bool) throwssetFillColor
public func setFillColor(_ layer: PDFLayer, _ color: PDFColor) throwsText colour, or a shape's fill.
setStrokeColor
public func setStrokeColor(_ layer: PDFLayer, _ color: PDFColor) throwssetStrokeWidth
public func setStrokeWidth(_ layer: PDFLayer, _ points: Double) throwssetOpacity
public func setOpacity(_ layer: PDFLayer, _ opacity: Double) throwssetFrame
public func setFrame(_ layer: PDFLayer, _ frame: CGRect) throwsMove and resize (text scales uniformly).
setRotation
public func setRotation(_ layer: PDFLayer, _ degrees: Double) throwsDegrees, clockwise as seen.
setZOrder
public func setZOrder(_ layer: PDFLayer, _ order: PDFZOrder) throwssetLink
public func setLink(_ layer: PDFLayer, _ url: URL?) throwsnil removes the link.
setSound
public func setSound(
_ layer: PDFLayer,
_ audio: Data,
name: String,
) throwsreplaceImage
public func replaceImage(_ layer: PDFLayer, with image: UIImage) throwsSwap an image layer's picture, keeping its frame and kind.
setMarkup
public func setMarkup(
_ layer: PDFLayer,
_ kind: PDFMarkupKind,
color: PDFColor,
) throwsMark a whole text layer up.
removeMarkup
public func removeMarkup(_ layer: PDFLayer) throwsRemove a text layer's highlight / strikeout / squiggly.
delete
public func delete(_ layer: PDFLayer) throwsduplicate
@discardableResult public func duplicate(
_ layer: PDFLayer,
offset: CGSize = CGSize(width: 12, height: 12),
) throws -> PDFLayerA copy offset by offset points.
copy
@discardableResult public func copy(
_ layer: PDFLayer,
toPage page: Int,
at origin: CGPoint,
) throws -> PDFLayerA copy on another page, its top-left at origin there.
addText
public func addText(
_ text: String,
page: Int,
at origin: CGPoint,
fontSize: Double = 14,
color: PDFColor = .black,
family: PDFFontFamily = .sans,
) throws -> PDFLayerA text layer with its top-left at origin.
addImage
public func addImage(
_ image: UIImage,
page: Int,
frame: CGRect,
kind: PDFImageKind = .photo,
note: String? = nil,
) throws -> PDFLayerAn image layer filling frame. A signature, a hand drawing or a stamp is an image of that kind.
addShape
public func addShape(
_ shape: PDFLayer.Shape,
page: Int,
from start: CGPoint,
to end: CGPoint,
fill: PDFColor = .clear,
stroke: PDFColor = .black,
strokeWidth: Double = 2,
) throws -> PDFLayerA rectangle or ellipse filling the rect from start to end, or a line / arrow from start to end.
markupText
public func markupText(
page: Int,
from start: CGPoint,
to end: CGPoint,
kind: PDFMarkupKind = .highlight,
color: PDFColor = PDFColor(rgba: 0xFFE44DFF),
) throwsMark up the text between two points of the page, as a drag with the tool would.
formFields
public func formFields() -> [PDFFormField]setFormValue
public func setFormValue(_ value: String, forField name: String) throwsFill a field: its text, an option's label, "true"/"false" for a check box, or the export value of the radio button to turn on.
fillForm
public func fillForm(_ values: [String: String]) throwsFill several fields at once.
addFormField
public func addFormField(
_ kind: PDFFormFieldKind,
page: Int,
frame: CGRect,
name: String? = nil,
options: [String] = [],
) throws -> StringA new field; returns its name (name, or one the editor made up). Radios that share a name are one set.
deleteFormField
public func deleteFormField(_ name: String) throwsRemove every widget called name (a whole radio set).
resetForm
public func resetForm() throwsflattenForm
public func flattenForm() throwsBake the fields into the pages (their values stay, they stop being editable).
PDFLayer.Kind
public enum Kind: String, SendablePDFLayer.Shape
public enum Shape: String, SendablePDFFormField.Kind
public enum Kind: String, SendableSDK, licensing and callbacks
PDFEditorLicense
public struct PDFEditorLicense: Sendable, Equatable, CustomStringConvertibleThe license verdict the SDK is running under.
status
public let status: StatusisLicensed
public let isLicensed: BoolTrue when the editor may open documents (valid or development).
reason
public let reason: StringOne sentence explaining status.
licensee
public let licensee: StringFrom the key (empty when there is none or it did not verify).
licenseID
public let licenseID: Stringplan
public let plan: Stringexpires
public let expires: String?YYYY-MM-DD, or nil for a key that does not expire.
updatesUntil
public let updatesUntil: String?YYYY-MM-DD: the last SDK release date the key covers, or nil for every release.
platform
public let platform: StringWhat the SDK checked: "ios" or "macos", and the bundle identifier it read.
identity
public let identity: StringisOnline
public var isOnline: Bool = falseTrue for an online key (confirmed with the vendor's license server).
paymentDue
public var paymentDue: Bool = falseOnline keys: the vendor marked the license's payment as overdue. It still works.
confirmedUntil
public var confirmedUntil: Date? = nilOnline keys: until when the current confirmation lets the app work offline (nil when there is none).
message
public var message: String = ""Online keys: the vendor's note to the developer, if any.
description
public var description: StringPDFEditorSDK
public enum PDFEditorSDKlicenseDidChangeNotification
public static let licenseDidChangeNotification = Notification.Name("PDFEditorSDKLicenseDidChange")Posted on the main queue after setLicenseKey(_:) runs, and when an online key's confirmation changes the verdict.
setLicenseKey
public static func setLicenseKey(_ key: String?) -> PDFEditorLicenseSet (or with nil clear) this app's license key. Returns the resulting verdict. Thread-safe; call it once at launch — application(_:didFinishLaunchingWithOptions:) or your App.init. For an online key the verdict may still be verificationRequired here, on the very first launch; the SDK confirms it in the background and posts licenseDidChangeNotification (an editor opened meanwhile waits for it).
refreshLicense
public static func refreshLicense() async -> PDFEditorLicenseOnline keys: ask the license server now (the SDK also does it at launch and on returning to the foreground). Returns the verdict afterwards; offline keys return at once.
license
public static var license: PDFEditorLicenseThe current license verdict.
version
public static let version: String = "2.4.1"The released version of this SDK, matching the git tag consumers resolve (e.g. 1.13.0).
PDFEditorLicense.Status
public enum Status: String, Sendable, Codablevalid
case validThe key covers this app.
development
case developmentA valid key on a development host (only the web SDK uses this).
unlicensed
case unlicensedNo key has been set. Locked.
invalid
case invalidThe key is malformed, altered, or was not issued by the vendor. Locked.
expired
case expiredThe key's expiry date has passed. Locked.
wrongApp
case wrongAppThe key does not name this app's bundle identifier. Locked.
wrongPlatform
case wrongPlatformThe key names no apps on this platform (iOS or macOS). Locked.
versionNotCovered
case versionNotCoveredThis SDK release is newer than the key's "updates until" date. Locked.
unknownSigningKey
case unknownSigningKeyThe key was issued under a signing key this SDK release does not know (update the SDK). Locked.
suspended
case suspendedAn online key the vendor has suspended. Locked until they resume it.
verificationRequired
case verificationRequiredAn online key not confirmed with the license server yet, or whose confirmation ran out. Locked until the app reaches the server.
iOS, iPadOS & Mac Catalyst
A complete editor UI you present with one view: PDFEditorView in SwiftUI or PDFEditorViewController in UIKit. Give it a PDF file, get the edited bytes back.
Android
A complete editor as a Jetpack Compose screen, PdfEditorScreen, or as a classic View, PdfEditorView. Hand it a file path, get the edited bytes back.