Xcode 11 beta 5:“不推荐使用'subscript(_ :)':有关迁移路径,请参见发行说明。”

时间:2019-08-18 11:45:48

标签: swift swiftui

我想使用如下代码:

import Foundation
import Combine
import SwiftUI

final class DataStore: ObservableObject {
    @Published var bools: [Bool] = [true, false]
}

struct ContentView: View {
    @EnvironmentObject var dataStore: DataStore
    var body: some View {
        HStack {
            Spacer()
            Toggle(isOn: $dataStore.bools[0]) {
                Text(dataStore.bools[0] ? "On" : "Off")
            }
            Spacer()
            Toggle(isOn: $dataStore.bools[1]) {
                Text(dataStore.bools[1] ? "On" : "Off")
            }
            Spacer()
        }
    }
}

(实际上,这段代码是没有用的,但是我只想传递一个数组元素作为对子视图的绑定。)

这在Xcode beta 2中有效,但是从beta 5开始,我在“ Toggle”两行中都收到以下警告:

  

'subscript(_ :)'已弃用:有关迁移路径,请参见发行说明。   当我尝试启动应用程序时,该应用程序崩溃了。

实际上,我已经读过release notes,并且我认为该问题与“删除了Binding结构对Collection协议的条件一致性”有关。
问题是我不理解如何将他们提供的示例代码与我要使用的代码一起使用。有人可以帮我吗?

2 个答案:

答案 0 :(得分:3)

Xcode 11,beta 6更新:

好消息!就像我怀疑的那样,在beta 6中,与Binding的{​​{1}}一致性已被其他替换。现在,它不再符合MutableCollection,而是让您通过MutableCollection访问元素。结果是您现在可以继续执行@dynamicMemberLookup而不再收到警告!

Xcode 11(测试版5)(旧答案)

如果要摆脱弃用,可以使用以下代码:

我用类似的东西回答了一个稍微不同的问题。在其他情况下,它是一个Binding,而不是ObservableObject(这就是为什么我不将其标记为重复的原因)。但是,基本知识是相同的:https://stackoverflow.com/a/57333200/7786555

我有一个感觉,在下一个Beta中,由于发行说明中存在一些矛盾,因此某些情况将再次发生变化。

dataStore.bools[0]

或者,您可以将解决方案用于另一个问题,该问题涉及扩展Binding:

final class DataStore: ObservableObject {
    @Published var bools: [Bool] = [true, false]

    func element(idx: Int) -> Binding<Bool> {
        return Binding<Bool>(get: { () -> Bool in
            return self.bools[idx]
        }) {
            self.bools[idx] = $0
        }
    }
}

struct ContentView: View {
    @EnvironmentObject var dataStore: DataStore
    var body: some View {
        HStack {
            Spacer()
            Toggle(isOn: dataStore.element(idx: 0)) {
                Text(dataStore.bools[0] ? "On" : "Off")
            }
            Spacer()
            Toggle(isOn: dataStore.element(idx: 1)) {
                Text(dataStore.bools[1] ? "On" : "Off")
            }
            Spacer()
        }
    }
}

答案 1 :(得分:0)

基于kontiki的非常有用的答案,我做了以下扩展,以便您可以像以前一样使用下标:

extension Binding where Value: MutableCollection, Value.Index == Int {
    public subscript(position: Value.Index) -> Binding<Value.Element> {
        Binding<Value.Element>(get: {
            self.wrappedValue[position]
        }, set: {
            self.wrappedValue[position] = $0
        })
    }
}

理论上,如果需要,您可以对下标(bounds :)做同样的事情。