RealityView annotations not updating

I have a RealityView that is an earth globe, where I'm adding attachments and also updating how attachments appear, depending on user input.

I pass a @Binding var annotations: [MyAnnotation] to my view which has a RealityView as its main body. The annotations are displayed fine using the SwiftUI views defined in the annotations handler, but they do not update when the annotations in that binding are updated.

My attachments: handler looks like this:

    RealityView { ...
    } attachments: {
      ForEach($annotations) { $attachment in
        AttachmentView(attachment: $attachment)
          .tag(attachment.id)
      }
    }

I also tried without the $ syntax there. Neither leads to an update of the AttachmentView. Curiously the update handler also isn't called when the annotations are updated.

I also tried settings a different .id on the entire thing, but even then it's just using my AttachmentView as initially configured.

I'm very puzzled by this and would appreciate help. Am I holding this wrong, or is this a bug?

Answered by Schoenig in 756908022

Okay, I've figured out a few things here, in case someone has similar issues:

  • I was holding it wrong in that there was an issue with changes not being picked up by the binding. After I fixed that, the attachments: handler did get called again. Hooray.
  • The old AttachmentView did stick around though, due to the IDs of my attachments changing when they changed shape. I fixed this by making sure those IDs are stable, and calling content.add(...) again in the update: handler then updated those to the new look.

The remaining issues was to get rid of all attachment entities if they disappear from my Binding. I'm not particularly happy with it, but the solution I came up with, was to collect the IDs and then iterate through all entities to check if their IDs are still in my set:

      let allEntities = Array(content.entities)
      for entity in allEntities {
        if let attachmentEntity = entity as? ViewAttachmentEntity, let id = attachmentEntity.attachment.id as? String, !goodIDs.contains(id) {
          content.remove(attachmentEntity)
        }
      }

Would love to know if there's a better way to do this.

Accepted Answer

Okay, I've figured out a few things here, in case someone has similar issues:

  • I was holding it wrong in that there was an issue with changes not being picked up by the binding. After I fixed that, the attachments: handler did get called again. Hooray.
  • The old AttachmentView did stick around though, due to the IDs of my attachments changing when they changed shape. I fixed this by making sure those IDs are stable, and calling content.add(...) again in the update: handler then updated those to the new look.

The remaining issues was to get rid of all attachment entities if they disappear from my Binding. I'm not particularly happy with it, but the solution I came up with, was to collect the IDs and then iterate through all entities to check if their IDs are still in my set:

      let allEntities = Array(content.entities)
      for entity in allEntities {
        if let attachmentEntity = entity as? ViewAttachmentEntity, let id = attachmentEntity.attachment.id as? String, !goodIDs.contains(id) {
          content.remove(attachmentEntity)
        }
      }

Would love to know if there's a better way to do this.

RealityView annotations not updating
 
 
Q