Lab 077 – Ornaments in Presentations?

We can add ornaments to popovers shown by PresentationComponent, but I’m not sure if we should.

While working on the editor in Project Graveyard, I had the idea to add ornaments to the view. The entire app exists inside a volume. A user can tap a gravestone to present a popoverUI to edit the item. This is displayed using the new PresentationComponent in visionOS 26. Ornaments have a new attachment anchor option this year: .parent().

.ornament(attachmentAnchor: .parent(.top), ornament: {...})

This works well in the Simulator. We can add ornaments around this popover view just like we would with a window.

visionOS Simulator showing a popover with ornaments

Unfortunately, when I run this on device I get a different experience. Any part of the ornament that overlaps with the popover content isn’t rendered correctly. Sometimes it entirely disappears, other times it becomes partially transparent.

ornaments being clipped by popover content

We could use content alignment to try to make sure the ornament doesn’t overlap the popover content.

.ornament(attachmentAnchor: .parent(.top), contentAlignment: .bottom, ornament: {...})

This works sometimes–but not all the time. It’s not clear if this is a bug or not, because I’m not sure if we are even supposed to be able to use ornaments in this way. Here is my hierarchy:

  • An app opens as a Volume
  • Volume presenting a RealityView, with its own ornament using .scene() anchor
  • Multiple Entities with Presentation Component show an edit view
  • The view uses .parent() anchor to add ornaments.

What makes me unsure is that other methods for drawing UI in RealityView don’t seem to work with ornaments. For example, if I add an attachment to show a view with the ornament–even when I use the .parent() anchor–the ornament is anchor to the volume, not the attachment view.

An attachment view with an ornament anchored to the volume

I decided to pull the ornaments from Project Graveyard for now until I can learn more about this. I’m going to post about this on the Apple Developer forum to see what other people thing. Is this a rendering bug? Are ornaments intended to work with attachments and presentations?

Lab Code

This lab extends Lab 064 to add ornaments to the view inside the popover.

struct Lab077: View {
    @State private var subject = Entity()
    @State private var showingPopover: Bool = false

    var body: some View {
        RealityView { content in

            guard let scene = try? await Entity(named: "PresentationComponentLab", in: realityKitContentBundle) else { return }
            content.add(scene)
            scene.position.y = -0.4

            // The main entity we are looking at
            guard let subject = scene.findEntity(named: "ToyRocket") else { return }
            self.subject = subject

            // A secondary entity that we can use as the transform point for the presented popover
            guard let presentationPoint = scene.findEntity(named: "PresentationPoint") else { return }

            // We'll use a TapGesture and the new GestureComponent to toggle the popover
            let tapGesture = TapGesture()
                .onEnded({
                    Entity.animate(.bouncy, body: {
                        showingPopover.toggle()
                    })
                })
            let gestureComponent = GestureComponent(tapGesture)
            subject.components.set(gestureComponent)

            // Create the presentation component using $showingPopover to toggle presentation
            let presentation = PresentationComponent(
                isPresented: $showingPopover,
                configuration: .popover(arrowEdge: .bottom),
                content: RocketCard(title: "PresentationComponent showing a Popover")
            )
            presentationPoint.components.set(presentation)
        }
    }
}

Rocket Card view

struct RocketCard: View {
    var title: String = "Rocket"
    var body: some View {
        VStack {

            VStack(spacing: 24) {
                Text(title)
                    .font(.caption)
                    .multilineTextAlignment(.center)
                Text("🚀")
                    .font(.largeTitle)
            }
            .frame(width: 200, height: 220)
            .padding()
            .ornament(attachmentAnchor: .parent(.top), ornament: {
                HStack {
                    Text("Top Ornament")
                }
                .padding()
                .glassBackgroundEffect()
            })
            .ornament(attachmentAnchor: .parent(.leading), ornament: {
                HStack {
                    Text("🚀")
                }
                .padding()
                .glassBackgroundEffect()
            })
            .ornament(attachmentAnchor: .parent(.trailing), ornament: {
                HStack {
                    Text("🚀")
                }
                .padding()
                .glassBackgroundEffect()
            })
        }
    }
}

Support our work so we can continue to bring you new examples and articles.

Download the Xcode project with this and many more labs from Step Into Vision.

Questions or feedback?