Binding an element of an array of an ObservableObject : 'subscript(_:)' is deprecated

后端 未结 2 1720
逝去的感伤
逝去的感伤 2020-12-15 06:38

I\'m using an ObservableObject \'DataStore\', which contains an array (\'exampleList\') of objects (\'exampleObject\').

@Published exampleList = [exampleObjec         


        
2条回答
  •  南方客
    南方客 (楼主)
    2020-12-15 06:52

    Xcode 11, beta 6 UPDATE:

    Good news! Just as I suspected, in beta 6, the Binding conformance to MutableCollection has been been replaced with something else. Instead of conforming to MutableCollection, it now let your access the elements via @dynamicMemberLookup. The result is you now can keep doing $text[3] and no longer get a warning! It seems this question can be closed now.

    Xcode 11, beta 5. Old answer:

    I finally got some time to investigate this a little. As I mentioned in the comments, I think it would be wise to wait until the Collection conformance is completely removed (or replaced with something else). But just to satisfy our curiosity, I have created an extension on Binding, that I think does what the current Collection conformance does. The only difference is that, instead of accessing through a subscript, I implemented a function called element(_ idx: Int) to get a Binding to the element.

    If one day the conformance is completely removed, I may change the implementation, and conform to Collection myself. I cannot do it now, because it would conflict with the existent (and deprecated) implementation. For the time being, I think this demonstrate how to handle the warnings if you absolutely want to get rid of them.

    Just to be clear. I am not using this code. As long as I can still access the elements through the subscript, I will still do it and ignore the warnings. This is just for academic purposes.

    The extension is:

    extension Binding where Value: MutableCollection, Value.Index == Int {
        func element(_ idx: Int) -> Binding {
            return Binding(
                get: {
                    return self.wrappedValue[idx]
            }, set: { (value: Value.Element) -> () in
                self.wrappedValue[idx] = value
            })
        }
    }
    

    And it can be used like this:

    struct MainView: View {
        @Binding var text: [String]
    
        var body: some View {
            TextField("", text: $text.element(0))
            TextField("", text: $text.element(1))
            TextField("", text: $text.element(2))
        }
    }
    

提交回复
热议问题