How it works
CompositorContentBuilder is the result builder that assembles the content you hand to a CompositorServices layer on visionOS, letting you describe a renderer's frame-by-frame work declaratively instead of imperatively wiring up draw calls. Reach for it when you build a fully immersive, Metal-driven experience with CompositorLayer and need to express the drawable content the compositor will display each frame. As an attribute, it transforms the statements inside a builder-annotated closure into a single composed content value, so you write a natural sequence of content declarations and the builder collects them for you. It plays the same structural role for compositor content that ViewBuilder plays for SwiftUI view hierarchies.
Apply @CompositorContentBuilder to your content closure
The builder is consumed as an attribute on a function or closure parameter that returns compositor content. Marking that closure with
@CompositorContentBuilderlets each statement inside it contribute to the composed result, the same way@ViewBuilderlets the statements in this demo'sbodystack up anImageand twoTextviews without an explicit collection.Let the builder collect a sequence of content declarations
Inside the annotated closure you list content declarations one after another and the builder combines them into one value, with no manual array or concatenation. That implicit accumulation is what turns the vertical run of children here --
Image(systemName: "visionpro")followed by the headline and captionText-- into a single returned result.Return the composed content from body-style members
Builder-annotated members behave like a computed
body: the builder synthesizes the return so you never write an explicitreturnfor a multi-statement closure. Thebodyproperty ofCompositorContentBuilderDemoshows the same shape, where the trailingVStackvalue is produced implicitly rather than returned by hand.Compose conditionally without breaking the result type
Because it is a result builder,
CompositorContentBuildersupportsif/switchand optional branches inside the closure while still yielding one uniform content type, so you can vary what gets composited based on state. You attach per-element configuration the same way the modifiers.font(.largeTitle),.foregroundStyle(.secondary), and.multilineTextAlignment(.center)decorate individual children before the builder gathers them.
Text("...") line right after the caption Text in the VStack to watch the builder fold an extra child into the composed result without any explicit collection syntax.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 CompositorContentBuilderDemo: View {
var body: some View {
VStack(spacing: 8) {
Image(systemName: "visionpro")
.font(.largeTitle)
Text("CompositorContentBuilder")
.font(.headline)
Text("Result builder for compositor layer content (visionOS / CompositorServices).")
.font(.caption)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
}
.padding()
}
}