What I do is wrap the Observable in an ObservableObject to hold the single intended instance
@Observable class Foo {
var value = 0
}
class FooHolder: ObservableObject {
let foo = Foo()
}
struct MyView: View {
@StateObject var holder = FooHolder()
var body: some View {
Text("\(holder.foo.value)")
}
}
The name isn’t as clean but I prefer that over pointless instantiation. However it gets worse if you want a Binding where my solution is to split it between 2 views, one to hold the instance the other for Bindable.
struct MyView: View {
@StateObject var holder = FooHolder()
var body: some View {
MyViewReal(foo: holder.foo)
}
}
struct MyViewReal: View {
@Bindable var foo: Foo
var body: some View {
Stepper("", value: $foo.value)
}
}
And of course you can make a generic holder class but a generic property name makes it unsatisfying to work with
class ObservableHolder<T: Observable>: ObservableObject {
let object: T
init(_ obj: T) { object = obj }
}