How it works
SquareAzimuth describes which of the four cardinal directions something is being viewed from along the horizontal plane, snapping a continuous viewing angle down to one of four discrete orientations. Reach for it on visionOS when you need to know roughly where a viewer is standing relative to your content — front, back, left, or right — without tracking the exact azimuth. Because it collapses a 360° range into four @frozen cases, it's well suited to driving coarse, side-aware layout or presentation decisions rather than fine-grained rotation. The example holds one such value in azimuth and uses it to orient an indicator on screen.
Hold an orientation in one of the four cases
SquareAzimuthis a frozen enum whose cases —back,front,left, andright— each correspond to a horizontal angle of 180°, 0°, 270°, and 90° respectively. You store or pass one the way the example declareslet azimuth: SquareAzimuth, giving downstream views a single, exhaustive value to switch on.Snap a continuous angle with init(closestToAzimuth:)
Rather than assigning a case by hand,
init(closestToAzimuth:)takes anAngleand returns the case whose orientation is closest to it — e.g. an input azimuth≥ 45°and< 135°resolves toright. This is the bridge from a measured, continuous viewing direction into the four-waySquareAzimuthbucket the example then renders.Read the snapped rotation from orientation
The
orientationproperty exposes the case as aRotation3Dsnapped to exactly0°,90°,180°, or270°. That gives you a ready-made 3D rotation to feed your content; in the 2D illustration the same idea is shown by mapping the value onto arotationEffect(.degrees(...))so theImagepoints the matching way.Combine directions with SquareAzimuth.Set
When you need more than one direction at once, the nested
SquareAzimuth.Setis anOptionSetwith members.front,.back,.left,.right, and.all. Build it from a single case viaSet(_:)or from a raw bitmask, and use it to express which sides a behavior should apply to.Compare and hash cases
Conformance to
EquatableandHashablemeans you can match cases with==, switch over them, or use them as dictionary keys and set members. The example leans on this indirectly throughString(describing: azimuth), which prints the active case name so you can confirm which direction is in play.
let azimuth: SquareAzimuth = .east to .right and watch both the rotationEffect rotation and the Text label update to reflect the new snapped direction.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 SquareAzimuthDemo: View {
let azimuth: SquareAzimuth = .east
var body: some View {
VStack(spacing: 12) {
Image(systemName: "location.north.line.fill")
.font(.largeTitle)
.rotationEffect(.degrees(Double(azimuth.rawValue) * 90))
Text("Azimuth: \(String(describing: azimuth))")
.font(.headline)
}
.padding()
}
}