I’m working with RealityView in visionOS and noticed that the content closure seems to run twice, causing content.add to be called twice automatically. This results in duplicate entities being added to the scene unless I manually check for duplicates. How can I fix that? Thanks.
I made a standalone project based on your code check this out. The good news that the entity is not being duplicated. Let's look at the cod first.
struct ImmersiveView: View {
@State var launchEntity = Entity()
var body: some View {
RealityView { content in
print("RealityView Content Loaded!") // Called Once
launchEntity = createLaunchEntity()
content.add(launchEntity)
}
}
func createLaunchEntity() -> Entity {
//...
let entity: Entity = Entity()
entity.name = "Launch Entity"
let launchviewComponent = ViewAttachmentComponent(
rootView: LaunchView()
)
entity.components.set(launchviewComponent)
print("createLaunchEntity was called") // Called Once
return entity
}
}
struct LaunchView: View {
var body: some View {
VStack {
Text("Launch View")
}
.padding()
.onAppear() {
print("Launch view appears!") // Called Twice
}
}
}
When I load this immersive space I see 4 lines in the console
RealityView Content Loaded!
createLaunchEntity was called
Launch view appears!
Launch view appears!
What happened
- RealityView content was called once
- createLaunchEntity
- The onAppear closure in the LaunchView was called twice.
That made me wonder if ViewAttachmentComponent
is calling LaunchView
more than once and yes, that appears to be the case.
When I create the attachment using the attachments closure on RealityView, onAppear is only called once.
var body: some View {
RealityView { content, attachments in
print("RealityView Content Loaded!") // Called Once
content.add(launchEntity)
if let attachment = attachments.entity(for: "Test") {
launchEntity = attachment
content.add(launchEntity)
}
} update: { content, attachments in
} attachments: {
Attachment(id: "Test", {
LaunchView()
})
}
}
So the good news is that we don't see duplicate entities in the graph. The bad news is that ViewAttachmentComponent
is calling the SwiftUI more than once. I suggest you file a bug with Feedback Assistant. In the meantime, you could using RealityView to create attachments. If your view is just presenting data, then I suppose you could just ignore this.