Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I force unwrap my $string to use as a TextField value?

This gives me the following error: Cannot force unwrap value of non-optional type 'Binding<Person?>

I don't understand why I can't force unwrap a binding?

struct Person {
    var name: String
}

struct ContentView: View {

    @State private var person: Person? = Person(name: "Peter")
    
    var body: some View {
        if person != nil {
            TextField("", text: $person!.name)
        }
    }
}
like image 688
Thomas Avatar asked Oct 21 '25 17:10

Thomas


1 Answers

When you declare a State variable in your view, you'll get a Binding to the value by adding a leading $ to the variable's name. So, in your code, you'll have a $person that is binding to an optional Person type. $person is Binding<Person?>

To pass value to TextField you'll need a Binding<String>. you can't force-unwrap $person because it's not an optional value. It's a Binding to an optional type. To access the name field inside the Person struct, you'll need a Binding<Person> instead. Fortunately, there's a method to get what you want. By using this initializer, you'll have a Binding<Person>?. Note that now instead of a Binding to an optional, you have an optional Binding. You should be able to use this new binding like this:

// Binding($person) returns Binding<Person>? 
TextField("", text: Binding($person)!.name)

Update: As @Jessy mentioned in the comments, instead of force-unwrapping the optional binding, we can use map to transform the returned Binding to a TextField

var body: some View {
   Binding($person).map {
     TextField("", text: $0.name)
   }
}
like image 78
Mohammad Rahchamani Avatar answered Oct 23 '25 07:10

Mohammad Rahchamani



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!