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

Shows the default, empty, error, and locked states of the PDFViewController. Get additional resources by visiting our PSPDFViewController API guide.


//
// Copyright © 2015-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
private enum ControllerState: String {
case normal
case empty
case error
case locked
func nextState() -> ControllerState {
switch self {
case .normal: return .empty
case .empty: return .error
case .error: return .locked
case .locked: return .normal
}
}
}
// MARK: CustomStringConvertible
extension ControllerState: CustomStringConvertible {
var description: String {
return "State: \(rawValue)"
}
}
class ControllerStateExample: Example {
// MARK: Properties
private weak var pdfController: PDFViewController?
private var toggleButton: UIBarButtonItem!
private var displayState: ControllerState = .normal {
didSet {
guard let pdfController else { return }
switch displayState {
case .normal:
pdfController.document = AssetLoader.document(for: .welcome)
case .empty:
pdfController.document = nil
case .error:
pdfController.document = Document(dataProviders: [DataContainerProvider(data: Data())])
case .locked:
pdfController.document = AssetLoader.document(for: "Password-Protected.pdf")
}
toggleButton.title = String(describing: displayState)
}
}
override init() {
super.init()
title = "Controller States"
contentDescription = "Shows default, empty, error, and locked states."
category = .controllerCustomization
toggleButton = UIBarButtonItem(title: "", style: .plain, target: self, action: #selector(ControllerStateExample.toggleButtonPressed(_:)))
}
@objc
private func toggleButtonPressed(_ sender: UIBarButtonItem) {
// If pressed, toggle to the next state.
displayState = displayState.nextState()
}
override func invoke(with delegate: ExampleRunnerDelegate) -> UIViewController {
let items = [toggleButton!]
let document = AssetLoader.document(for: .welcome)
pdfController = {
let pdfController = PDFViewController(document: document)
for viewMode: ViewMode in [.document, .documentEditor, .thumbnails] {
pdfController.navigationItem.setRightBarButtonItems(items, for: viewMode, animated: false)
}
pdfController.barButtonItemsAlwaysEnabled = items
return pdfController
}()
// Set displayState to trigger toggleButton title change
displayState = .normal
return pdfController!
}
}

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