将结构数组与结构数组中的字符串绑定
Binding Array of Structs with Strings in an Array of Structs
我是 Swift 的新手,所以我希望这不是什么傻事。我正在尝试构建一个结构数组,其中一个参数是另一个包含另一个结构的数组。我不确定是否有更好的方法,但我认为在尝试编辑嵌入式结构之前我已经取得了很好的进展。在它的简化形式中,它看起来像这样......
struct Group: Identifiable, Codable {
var id = UUID()
var name: String
var number: Int
var spaces: Bool
var businesses: [Business]
}
struct Business: Identifiable, Codable {
var id = UUID()
var name: String
var address: String
var space: Int
var enabled: Bool
}
这些在 class 中使用,带有存储在用户默认值中的 Observable 变量
class GroupSettings: ObservableObject {
@Published var groups = [Group]() {
didSet {
UserDefaults.standard.set(try? PropertyListEncoder().encode(groups), forKey: "groups")
}
}
init() {
if let configData = UserDefaults.standard.value(forKey: "groups") as? Data {
if let userDefaultConfig = try?
PropertyListDecoder().decode(Array<Group>.self, from: configData){
groups = userDefaultConfig
}
}
}
}
它已传递到我的初始视图,然后我想制作一个“编辑详细信息”屏幕。当它到达编辑详细信息屏幕时,我可以在文本显示中显示业务信息,但我无法使用 TextField,它抱怨无法将 a 转换为 Binding,但名称来自初始结构工作正常,类似的问题与 Int ...
我使用 @Binding 属性 ...
将一个组从第一个视图(其中包含组数组)传递到详细信息屏幕
@Binding var group: Group
var body: some View {
TextField("", text: $group.name) <---- WORKS
List {
ForEach(self.group.businesses){ business in
if business.enabled {
Text(business.name) <---- WORKS
TextField("", business.address) <---- FAILS
TextField("", value: business.space, formatter: NumberFormatter()) <---- FAILS
} else {
Text("\(business.name) is disabled"
}
}
}
}
希望我已经很好地解释了自己,并且有人可以指出我的方法的错误。我确实尝试将第二个结构嵌入到第一个结构中,但这没有帮助。
提前致谢!
您可以在 ForEach
中使用 indices
,然后仍然使用 $group
并通过这样的索引访问业务索引...
List {
ForEach(group.businesses.indices) { index in
TextField("", text: $group.businesses[index].address)
}
}
另一种解决方案可能是使用 zip
(或 )同时拥有企业及其指数:
struct TestView: View {
@Binding var group: Group
var body: some View {
TextField("", text: $group.name)
List {
let items = Array(zip(group.businesses.indices, group.businesses))
ForEach(items, id: \.1.id) { index, business in
if business.enabled {
Text(business.name)
TextField("", text: $group.businesses[index].address)
} else {
Text("\(business.name) is disabled")
}
}
}
}
}
我是 Swift 的新手,所以我希望这不是什么傻事。我正在尝试构建一个结构数组,其中一个参数是另一个包含另一个结构的数组。我不确定是否有更好的方法,但我认为在尝试编辑嵌入式结构之前我已经取得了很好的进展。在它的简化形式中,它看起来像这样......
struct Group: Identifiable, Codable {
var id = UUID()
var name: String
var number: Int
var spaces: Bool
var businesses: [Business]
}
struct Business: Identifiable, Codable {
var id = UUID()
var name: String
var address: String
var space: Int
var enabled: Bool
}
这些在 class 中使用,带有存储在用户默认值中的 Observable 变量
class GroupSettings: ObservableObject {
@Published var groups = [Group]() {
didSet {
UserDefaults.standard.set(try? PropertyListEncoder().encode(groups), forKey: "groups")
}
}
init() {
if let configData = UserDefaults.standard.value(forKey: "groups") as? Data {
if let userDefaultConfig = try?
PropertyListDecoder().decode(Array<Group>.self, from: configData){
groups = userDefaultConfig
}
}
}
}
它已传递到我的初始视图,然后我想制作一个“编辑详细信息”屏幕。当它到达编辑详细信息屏幕时,我可以在文本显示中显示业务信息,但我无法使用 TextField,它抱怨无法将 a 转换为 Binding,但名称来自初始结构工作正常,类似的问题与 Int ...
我使用 @Binding 属性 ...
将一个组从第一个视图(其中包含组数组)传递到详细信息屏幕@Binding var group: Group
var body: some View {
TextField("", text: $group.name) <---- WORKS
List {
ForEach(self.group.businesses){ business in
if business.enabled {
Text(business.name) <---- WORKS
TextField("", business.address) <---- FAILS
TextField("", value: business.space, formatter: NumberFormatter()) <---- FAILS
} else {
Text("\(business.name) is disabled"
}
}
}
}
希望我已经很好地解释了自己,并且有人可以指出我的方法的错误。我确实尝试将第二个结构嵌入到第一个结构中,但这没有帮助。
提前致谢!
您可以在 ForEach
中使用 indices
,然后仍然使用 $group
并通过这样的索引访问业务索引...
List {
ForEach(group.businesses.indices) { index in
TextField("", text: $group.businesses[index].address)
}
}
另一种解决方案可能是使用 zip
(或
struct TestView: View {
@Binding var group: Group
var body: some View {
TextField("", text: $group.name)
List {
let items = Array(zip(group.businesses.indices, group.businesses))
ForEach(items, id: \.1.id) { index, business in
if business.enabled {
Text(business.name)
TextField("", text: $group.businesses[index].address)
} else {
Text("\(business.name) is disabled")
}
}
}
}
}