Deepak Sharma
Deepak Sharma

Reputation: 6581

SwiftUI optional state variable binding with if let

The code below does not build. How do I make it work?

import SwiftUI

struct TestView: View {
    
    @State var model:TestModel?
    
    var body: some View {
        
        if let model = model {
            OverlayTestView(textVM: model) 
//Error: Cannot convert value of type 'TestModel' to expected argument type 'Binding<TestModel>'
        } else {
            ProgressView()
                .task {
                    model = TestModel()
                }
        }
       
            
    }
}

struct OverlayTestView: View {
    @Binding var textVM:TestModel
    
    var body:some View {
        Text("Count \(textVM.counter)")
    }
}

@Observable
class TestModel {
    var counter:Int = 0
}
 

Upvotes: 0

Views: 110

Answers (2)

Toni Hoffmann
Toni Hoffmann

Reputation: 41

One solution to fix this to use a Binding with a get and set like in this example:

import SwiftUI

struct TestView: View {
    @State var model: TestModel?
    
    var body: some View {
        if let model = $model.wrappedValue {
            OverlayTestView(textVM: Binding(
                get: { model },
                set: { model in self.model = model }
            ))
        } else {
            ProgressView()
                .task {
                    model = TestModel()
                }
        }
    }
}

struct OverlayTestView: View {
    @Binding var textVM: TestModel
    
    var body: some View {
        Text("Count \(textVM.counter)")
    }
}

@Observable
class TestModel {
    var counter: Int = 0
}

You could also define this as a getter variable

    var projectedValue: Binding<Value> {
        Binding(
            get: { wrappedValue ?? defaultValue },
            set: { wrappedValue = $0 }
        )
    }

Upvotes: 1

lorem ipsum
lorem ipsum

Reputation: 29614

Change @Binding to @Bindable, @Binding is for value types.

If you need $ in TestView just and @Bindable in the line after if let

@Bindable var model = model

Upvotes: 2

Related Questions