How it works
PencilHoverPose is a value type that captures the geometry of an Apple Pencil as it hovers above the display, before its tip makes contact. It reports where the Pencil is pointing and how far it sits from the glass, giving you the spatial information needed to preview strokes, highlight targets, or adjust a tool under the user's hand. Reach for PencilHoverPose when you want your interface to react to an approaching Pencil rather than waiting for a touch — the system delivers a fresh pose to you on each hover update.
Receive a pose from a hover phase
A
PencilHoverPosedoesn't arrive on its own; the system hands it to you inside a hover phase as the Pencil moves over your view. In the example, the.activecase of the phase carries the pose, which is bound withif case .active(let pose) = phaseso the rest of the closure can read its properties.Read the tilt with altitude
The
altitudeproperty reports the angle of the Pencil relative to the screen surface, in radians — a value near zero means the Pencil lies almost flat, while a larger angle means it stands more upright. The example forwardspose.altitudeinto itsaltitudestate so the reading updates as the user changes the Pencil's tilt.Read the distance with zOffset
The
zOffsetproperty describes how far the Pencil tip is from the display along the perpendicular axis, letting you gauge proximity as the Pencil descends toward the glass. Herepose.zOffsetis stored in thezOffsetstate and shown in points, so the value shrinks as the Pencil nears the surface.Drive a view from the live pose
Because
PencilHoverPoseis a plain value, you can copy its members straight into@Stateand let SwiftUI re-render. The example writes bothpose.altitudeandpose.zOffsetinto state inside the.onPencilHovercallback, and theTextviews update on every hover update without any extra plumbing.
Text(String(format: "Tip distance class: %@", zOffset < 10 ? "close" : "far")) next to the existing readouts so you can watch the threshold flip as pose.zOffset changes while you raise and lower the Pencil.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct PencilHoverPoseDemo: View {
@State private var altitude: Double = 0
@State private var zOffset: Double = 0
var body: some View {
VStack(spacing: 12) {
Text("Hover an Apple Pencil")
.font(.headline)
Text(String(format: "Altitude: %.2f rad", altitude))
Text(String(format: "Z offset: %.1f pt", zOffset))
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.blue.opacity(0.1))
.onPencilHover { phase in
if case .active(let pose) = phase {
altitude = pose.altitude
zOffset = pose.zOffset
}
}
}
}