PreviewProvider view initializer compiler error with @Binding

From my question that was answered here, I'm now not able to figure out how to make Canvas work when there's an @Binding in the struct. My variation is now this toy code:

struct RootView: View {
  @Binding var thingToUse: Thing

  var body: some View {

  // body code that compiles without error
  }
}

struct RootView_Previews: PreviewProvider {
  static var previews: some View {
    var thingToPreview = Thing()  // ERROR

    RootView(thingToUse: thingToPreview)
  }
}

This one gives the error, "Cannot convert value of type 'Thing' to expected argument type 'Binding'". Wrapping the preview's var with @Binding doesn't make sense either. I tried anyway and got, "Cannot declare local wrapped variable in result builder." Other stuff I've tried doesn't compile, which means I still don't fully comprehend the logic here. How do I make that preview compile?

Answered by robnotyou in 708292022

Try this:

struct RootView_Previews: PreviewProvider {
    static var previews: some View {
        let thingToPreview = Thing()
        RootView(thingToUse: .constant(thingToPreview))
    }
}
Accepted Answer

Try this:

struct RootView_Previews: PreviewProvider {
    static var previews: some View {
        let thingToPreview = Thing()
        RootView(thingToUse: .constant(thingToPreview))
    }
}

That's one of SwiftUI intricacies…

You should write this:

struct RootView: View {
    @Binding var thingToUse: Int
    
    var body: some View {
        Text("Hello")
        // body code that compiles without error
    }
}

struct StatefulPreviewWrapper<Value, Content: View>: View {
    @State var value: Value
    var content: (Binding<Value>) -> Content

    var body: some View {
        content($value)
    }

    init(_ value: Value, content: @escaping (Binding<Value>) -> Content) {
        self._value = State(wrappedValue: value)
        self.content = content
    }
}

struct RootView_Previews: PreviewProvider {
  static var previews: some View {
    var thingToPreview = 0  // ERROR

      StatefulPreviewWrapper(thingToPreview) { RootView(thingToUse: $0) }
    
  }
}

Credit: https://developer.apple.com/forums/thread/118589

The error is, " "Cannot convert value of type 'Thing' to expected argument type 'Binding'". "

I tried the first suggestion from robnotyou, and it seems to work without any unpleasant side effect. After voting it as the answer, the system won't let me also choose the other answer from Claude31.

I've studied Claude31's answer and the info at the other thread, and I see it addresses my situation exactly. It was good to study to understand why my error happens in the first place, even if I don't yet fully understand this intricacy yet. I do want to ask: since the first solution is a lot simpler, does it risk any bad side effects somewhere along the line? I mean, why implement a stateful preview wrapper if you can just coerce the thing to preview into a constant via .constant()?

PreviewProvider view initializer compiler error with @Binding
 
 
Q