This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/ios/samples/customizing-pdf-form-appearance.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Customize PDF form appearance in Swift for iOS

Customize the Appearance of Forms. Get additional resources by visiting our guide on supported PDF form fields in iOS.


//
// Copyright © 2020-2026 PSPDFKit GmbH. All rights reserved.
//
// The Nutrient sample applications are licensed with a modified BSD license.
// Please see License for details. This notice may not be removed from this file.
//
import PSPDFKit
import PSPDFKitUI
/// This example shows how to customize the appearance of forms. We also add a
/// temporary label over text and signature fields which will disappear when
/// we type anything in the fields.
class CustomizingFormAppearanceExample: Example {
override init() {
super.init()
title = "Customizing the Appearance of Forms"
contentDescription = "Also adds labels over empty text and signature fields."
category = .forms
priority = 10
}
override func invoke(with delegate: ExampleRunnerDelegate) -> UIViewController {
let document = AssetLoader.writableDocument(for: "Form.pdf", overrideIfExists: true)
/// These options clear out the default form field color so that
/// we can customize it dynamically later in the example.
let options = document.renderOptions(forType: .page)
options.drawSignHereOverlay = false
options.interactiveFormFillColor = UIColor.clear
document.setRenderOptions(options, type: .page)
let controller = PDFViewController(document: document) {
$0.pageTransition = .scrollPerSpread
$0.overrideClass(PDFPageView.self, with: CustomFormPDFPageView.self)
}
controller.delegate = self
styleTextFieldFormElements(in: document)
return controller
}
private func styleTextFieldFormElements(in document: Document) {
let annotations = document.annotationsForPage(at: 0, type: .widget)
for annotation in annotations {
if let formElement = annotation as? TextFieldFormElement {
formElement.highlightColor = UIColor.clear
formElement.fillColor = UIColor(red: 221.0 / 255.0, green: 240.0 / 255.0, blue: 236.0 / 255.0, alpha: 1)
formElement.borderColor = UIColor.clear
formElement.borderStyle = .none
formElement.borderEffectIntensity = 0.0
}
}
}
}
extension CustomizingFormAppearanceExample: PDFViewControllerDelegate {
func pdfViewController(_ pdfController: PDFViewController, willBeginDisplaying pageView: PDFPageView, forPageAt pageIndex: Int) {
if let pageView = pageView as? CustomFormPDFPageView {
pageView.addLabels()
}
}
}
private class CustomFormPDFPageView: PDFPageView {
/// Dictionary which keeps a mapping between the form element and its label.
/// Used to identify which label to remove when selecting a form field.
var labelList = [String: UILabel]()
override var frame: CGRect {
didSet {
// Re-add labels when page view frame changes
labelList.values.forEach { $0.removeFromSuperview() }
labelList.removeAll()
addLabels()
}
}
/// `prepareForReuse` automatically removes all unknown internal subviews.
/// We need to clear out our mapping dictionary as well.
override func prepareForReuse() {
labelList.removeAll()
super.prepareForReuse()
}
/// Add labels over all the text and signature fields.
func addLabels() {
guard let document = presentationContext?.document else { return }
let annotations = document.annotationsForPage(at: pageIndex, type: .widget)
for annotation in annotations {
if let formElement = annotation as? FormElement {
addLabelOnFormElement(formElement: formElement)
}
}
}
/// Add the label on a given form element. Only add a label if the form field is empty.
func addLabelOnFormElement(formElement: FormElement) {
if !(formElement.isKind(of: TextFieldFormElement.self) || formElement.isKind(of: SignatureFormElement.self)) { return }
let label = labelList[formElement.uuid] ?? UILabel()
if let textFieldFormElement = formElement as? TextFieldFormElement {
if textFieldFormElement.contents != nil && textFieldFormElement.contents != "" { return }
label.text = textFieldFormElement.textFormField?.name ?? "Text Field"
}
if let signatureFormElement = formElement as? SignatureFormElement {
if signatureFormElement.isSigned || signatureFormElement.overlappingSignatureAnnotation != nil { return }
label.text = "Signature Field"
}
label.frame = convert(formElement.boundingBox, from: pdfCoordinateSpace)
label.textAlignment = .center
label.textColor = UIColor(red: 84.0 / 255.0, green: 178.0 / 255.0, blue: 159.0 / 255.0, alpha: 1)
label.backgroundColor = UIColor(red: 221.0 / 255.0, green: 240.0 / 255.0, blue: 236.0 / 255.0, alpha: 1)
annotationContainerView.addSubview(label)
labelList[formElement.uuid] = label
}
override func didSelect(_ annotations: [Annotation]) {
super.didSelect(annotations)
for annotation in annotations {
if let label = labelList[annotation.uuid] {
labelList[annotation.uuid] = nil
label.removeFromSuperview()
}
if let textFieldFormElement = annotation as? TextFieldFormElement {
textFieldFormElement.borderColor = UIColor(red: 84.0 / 255.0, green: 178.0 / 255.0, blue: 159.0 / 255.0, alpha: 1)
textFieldFormElement.borderStyle = .solid
textFieldFormElement.borderEffectIntensity = 1.0
}
}
}
override func didDeselect(_ annotations: [Annotation]) {
super.didDeselect(annotations)
for annotation in annotations {
if let textFieldFormElement = annotation as? TextFieldFormElement {
textFieldFormElement.borderColor = UIColor.clear
textFieldFormElement.borderStyle = .none
textFieldFormElement.borderEffectIntensity = 0.0
}
if let formElement = annotation as? FormElement {
addLabelOnFormElement(formElement: formElement)
}
if let inkAnnotation = annotation as? InkAnnotation {
if inkAnnotation.isSignature { addLabels() }
}
}
}
}

This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.