我很好奇,我们如何指定对属于可选部分的状态数据的绑定?例如:
struct NameRecord {
var name = ""
var isFunny = false
}
class AppData: ObservableObject {
@Published var nameRecord: NameRecord?
}
struct NameView: View {
@StateObject var appData = AppData()
var body: some View {
Form {
if appData.nameRecord != nil {
// At this point, I *know* that nameRecord is not nil, so
// I should be able to bind to it.
TextField("Name", text: $appData.nameRecord.name)
Toggle("Is Funny", isOn: $appData.nameRecord.isFunny)
} else {
// So far as I can tell, this should never happen, but
// if it does, I will catch it in development, when
// I see the error message in the constant binding.
TextField("Name", text: .constant("ERROR: Data is incomplete!"))
Toggle("Is Funny", isOn: .constant(false))
}
}
.onAppear {
appData.nameRecord = NameRecord(name: "John")
}
}
}
我当然可以看到我错过了一些东西。 Xcode 给出类似错误Value of optional type 'NameRecord?' must be unwrapped to refer to member 'name' of wrapped base type 'NameRecord'
)并提供了一些没有帮助的 FixIts。
根据用户“workingdog support乌克兰”的回答,我现在知道如何绑定到我需要的部分,但是该解决方案对于具有许多不同类型字段的记录不能很好地扩展。
鉴于可选部分位于中间appData.nameRecord.name
,似乎可能有一个解决方案可以执行类似于 SwiftUI 标头中的以下函数可能执行的操作:
public subscript<Subject>(dynamicMember keyPath: WritableKeyPath<Value, Subject>) -> Binding<Subject> { get }
我的 SwiftFu 不够,所以我不知道这是如何工作的,但我怀疑这就是为类似的事情做的工作$appData.nameRecord.name
当 nameRecord 不是可选的时。我想要这个函数会导致绑定到的东西.constant
当 keyPath 中的任何内容为零时(或者即使它执行了 fatalError,我会使用上面的条件来避免)。如果有一种方法可以获得像以下一样优雅的解决方案,那就太好了乔纳森的回答 https://stackoverflow.com/a/61002589/14840926工作狗也针对类似情况提出了这样的建议。该领域的任何指示将不胜感激!