Sample CodeiOS, iPadOS, Mac CatalystReviewed 2026-07-21View on Apple Developer

Integrating pointer interactions into your iPad app

At a glance

Item Summary
Purpose Demonstrates button pointer providers, custom regions/shapes/effects, modifier keys, hover gestures, context menus, and trackpad scrolling.
App architecture One screen controller coordinates interactions; custom views own geometry/state, while capability extensions separate pointer, button-provider, and context-menu callbacks.
Main patterns Controller adapter, polymorphic shape strategy, capability extensions, and custom-control encapsulation.
Project style Storyboard feature screen with behavior divided by UIKit interaction contract rather than by traditional service layers.

Project structure

PointerInteraction/
├── ViewController.swift
├── ViewController+PointerInteraction.swift
├── ViewController+ButtonProvider.swift
├── ViewController+ContextMenu.swift
├── ShapeView.swift
├── AlphaControl.swift
├── AppDelegate.swift
├── SceneDelegate.swift
└── Base.lproj/Main.storyboard

Structure observations

  • ViewController.swift owns assembly and gestures; three extensions isolate unrelated interaction contracts.
  • Shape subclasses share hit testing and preview construction in ShapeView, overriding only path geometry.
  • AlphaControl contains its drawing, labels, pan-to-alpha logic, and preview path in one custom control.

Overall architecture

Reference code

PointerInteraction/ViewController.swift:24 — the controller installs interactions, but asks each custom view for the geometry used by those interactions.

// Set the alpha control's color, and add a pointer interaction.
alphaControl.currentColor = UIColor.systemOrange
alphaControl.addInteraction(UIPointerInteraction(delegate: self))

setupShapeView(shapeView: ovalShape, color: UIColor.systemRed, label: "Lift")
setupShapeView(shapeView: roundRectShape, color: UIColor.systemGreen, label: "Highlight")
setupShapeView(shapeView: triangleShape, color: UIColor.systemGray, label: "Hover")
setupShapeView(shapeView: squareShape, color: UIColor.systemBlue, label: "Automatic")

Interpretation

The controller is the shared UIKit delegate because it coordinates several view types, but it does not duplicate geometry. ShapeView.targetedPreview(), innerPath, and AlphaControl.highlightRegion keep visual knowledge at the view boundary.

Ownership and state

Ownership evidence

PointerInteraction/ShapeView.swift:10 — the base view owns reusable visual geometry and effect label state that its subclasses specialize.

class ShapeView: UIView {
    // ...
}
Owner State Relationship Mutation authority
Storyboard/controller Shape/control instances Storyboard creates; controller configures Setup and gesture callbacks
ShapeView Paths, colors, effect name/label Owns view geometry Base/subclass drawing and controller gestures
AlphaControl Current color/alpha and child labels/swatch Owns custom-control state Pan gesture and setup methods
Controller extensions No separate stored state Same controller split across files UIKit callbacks

Class and protocol design

Type Responsibility Design note
ViewController Assemble interactions and coordinate gestures/modifiers Shared adapter for several UIKit protocols
ShapeView Draw path, hit-test, build targeted preview Base strategy with reusable geometry contract
Shape subclasses Override pathViewForFrame(_:) Polymorphism is limited to shape generation
AlphaControl Render and edit alpha using direct touch or continuous scroll Self-contained UIControl subclass
ButtonPointerEffectKind Map storyboard button tags to styles Target-local enum in button-provider extension

There is no app-defined protocol. UIKit delegate protocols are applied in capability-specific extensions; subclassing provides the one app-defined polymorphic seam for shape geometry.

Access control

Symbol Access Verified effect Rationale
ShapeView.imageView and innerInset private Subclasses cannot depend on internal child-view layout. Base view protects its rendering implementation.
AlphaControl constants and labels private External code changes only semantic color/alpha properties. Maintains custom-control layout invariants.
Controller outlets/helpers and shape geometry implicit internal Extensions in separate files and storyboard feature code share them. Capability file split requires target-level visibility.
Types implicit internal App target only. No public framework is produced.
fileprivate / public none No file-only or exported API surface is declared. Collaboration is either private-to-type or target-local.

Reference code

PointerInteraction/AlphaControl.swift:12 — semantic state is target-visible for setup, while child views and drawing constants remain private.

var currentColor = UIColor.gray
var currentAlpha: CGFloat = 1.0

static let regionIdentifier: AnyHashable = "colorPath"

private let marginSpacing: CGFloat = 6.0
private let cornerRadius: CGFloat = 12.0

private var colorSwatch: UIView!
private var colorLabel: UILabel!
private var valueLabel: UILabel!

Logic ownership and placement

Logic Owner or file Why it belongs there
Interaction/gesture assembly ViewController.swift One screen coordinates all interactive components.
Region/style/enter-exit callbacks +PointerInteraction.swift Direct implementation of one UIKit contract.
Button tag-to-style mapping +ButtonProvider.swift Specific to UIButton.pointerStyleProvider.
Context-menu actions/previews +ContextMenu.swift Separate capability sharing shape previews.
Path generation/hit testing ShapeView hierarchy Must agree with drawn geometry.
Alpha scrolling/drawing AlphaControl Custom control owns its displayed value and child views.

Design patterns

Pattern Source evidence Purpose or tradeoff
Controller as interaction adapter PointerInteraction/ViewController+PointerInteraction.swift:10 Reuses one delegate across heterogeneous views.
Strategy by subclass PointerInteraction/ShapeView.swift:87 Specializes geometry through one override.
Capability extensions PointerInteraction/ViewController+ContextMenu.swift:10 Keeps callback families readable while sharing controller state.
Custom control encapsulation PointerInteraction/AlphaControl.swift:10 Couples semantic value, gestures, preview path, and rendering coherently.
Tag-to-enum mapping PointerInteraction/ViewController+ButtonProvider.swift:11 Turns storyboard integer tags into named effect cases.

Naming conventions

  • Shape subclasses name geometry directly: TriangleShapeView, RoundrectShapeView, and OvalShapeView.
  • Capability files use ViewController+... suffixes that match UIKit features.
  • targetedPreview, highlightRegion, and regionIdentifier use pointer/context-menu vocabulary consistently.
  • setup..., pan..., tap..., scale..., and hover... distinguish configuration from gesture commands.

Architecture takeaways

  • Keep pointer preview paths and hit-testing geometry in the custom view that draws the shape.
  • Split one interaction-heavy controller by framework capability when callbacks share the same state owner.
  • Use a small override point when visual variants differ only in geometry.
  • Expose semantic control state while keeping child views and layout constants private.

Source map

Source file Relevant symbols
PointerInteraction/ViewController.swift Assembly and gestures
PointerInteraction/ViewController+PointerInteraction.swift Regions, styles, enter/exit animation
PointerInteraction/ViewController+ButtonProvider.swift Button style provider
PointerInteraction/ViewController+ContextMenu.swift Context menu and targeted preview
PointerInteraction/ShapeView.swift Shape hierarchy, drawing, hit testing
PointerInteraction/AlphaControl.swift Scrollable alpha custom control