swiftuiobservablensviewrepresentable

How to watch changes of an @Observable class in NSViewRepresentable


I have an @Observable class in the environment:

@Observable class AnnotationsCoordinator {
    var annotations = [Annotation]()
}

In my parentView:

...

@State var annotationsCoordinator = AnnotationsCoordinator()

...

var body: some View {
    MyCustomTextView()
        .environment(annotationsCoordinator)
}

Finally MyCustomTextView:

struct MyCustomTextView: NSViewRepresentable {
    @Environment(AnnotationsCoordinator.self) private var annotationsCoordinator: AnnotationsCoordinator

    func makeCoordinator() -> MyViewCoordinator {
        Coordinator(self, annotationsCoordinator)
    }

    func makeNSView(context: Context) -> NSView {
        context.coordinator.myTextView
    }

    func updateNSView(_ view: NSView, context: Context) {
        if let sv = context.coordinator.textView as? MyTextView {
            // redraw with new annotations
        }
    }
}

How can I observe changes in annotationsCoordinator so I can use them in MyTextView ?


Solution

  • You just have to use annotations somewhere so add

    print(annotationsCoordinator.annotations)
    

    to updateNSView

    or do something like

    let _ = annotationsCoordinator.annotations
    

    updateNSView will get called when they change.

    SwiftUI needs to know that a redraw is needed and it does that based on where the properties are being used.