Search code examples
iosswiftbindingswiftuiproperty-wrapper

Using @Binding with type casting in swiftui


My data model:

class MyData: ObservableObject {
    @Published var aabbData = [AabbData]()
}

struct AbData: AabbData{
    var x = 0
}

protocol AabbData{

}

In my view code, i want to downcast aabbData's element to AbData type, and bind its x property to a control's value. So i try to code this:

@EnvironmentObject var data: MyData
let index = 0

//some other code

//method 1
Slider(value: ($data.aabbData[index] as! Binding<AbData>).x, in: -100...100, step: 1)
//error: Cast from 'Binding<AabbData>' to unrelated type 'Binding<AbData>' always fails

//method 2
Slider(value: Binding<Int>(
    get:{
        (data.aabbData[index] as! AbData).x
    },
    set:{
        (data.aabbData[index] as! AbData).x = $0
        //error: Cannot assign to immutable expression of type 'Int'
    }
), in: -100...100, step: 1)

The code is not working. How can i bind the downcast value's property to control's value?


Solution

  • The Binding type allow for both reading and writing. Since you can't safely read the value of an AabbData and assume it's an AbData this cannot work.

    If you want to try anyway, then you'll have to create a new Binding (possibly with the Binding(get:set:) constructor) that does the casting there.

    For example, noting that this forced cast is probably not advisable for all the usual reasons:

    let binding = Binding<AbData>(get: {
        data.aabbData[index] as! AbData
    }, set: {
        data.aabbData[index] = $0
    })