SwiftUI - 列出嵌套数组中的元素 [英] SwiftUI - List elements within nested array
问题描述
我正在尝试在列表视图中显示顶级数组中的元素.数据模型的构建方式是,它是一个事件数组,然后在该数组中,有一个与各个事件相关联的场所数组.
I'm trying to display elements from a top level array in a list view. The data model is constructed in a way that it's an array of events and then within that array there's an array of venues associated with the individual events.
在主视图中,我知道如何通过索引显示单个事件标题,但我不确定如何使用 ForEach 列出所有不同的事件.
In the main view, I know how to display an individual event title by it's index, but I'm not sure how to use ForEach to list all the different events.
Passports.swift(数据模型)
Passports.swift (Data model)
import Foundation
import SwiftUI
struct Passport: Identifiable {
let id : Int
let passportPremium: Bool
let passportActive: Bool
let passportTitle: String
let passportDates: String
let venues: [Venue]
}
struct Venue: Identifiable {
let id = UUID()
let title : String
let venueArea: String
let venueItems: [venueItem]
}
struct venueItem {
let title: String
let productDescription: String
let productPrice: Double
let productType: String
let newStatus: Bool
let diningPlan: Bool
let kidFriendly: Bool
let vegetarian: Bool
let glutenFree: Bool
let featuredProduct: Bool
let containsAlcohol: Bool
}
extension Passport {
static func all() -> [Passport] {
return [
Passport (
id: 1001,
passportPremium: false,
passportActive: true,
passportTitle : "Event 1",
passportDates: "October 20 - November 3, 2019",
venues: [
Venue (
title: "Bavaria Holiday Kitchen",
venueArea: "Germany Pavilion",
venueItems: [
venueItem (
title: "Potato Dumpling",
productDescription: "Potato Dumpling with Mushroom Sauce",
productPrice: 0.00,
productType: "Food",
newStatus: false,
diningPlan: false,
kidFriendly: true,
vegetarian: false,
glutenFree: false,
featuredProduct: false,
containsAlcohol: false
)
] // End VenueItems
) // End Venue
] // End Venues
),
Passport (
id: 1002,
passportPremium: false,
passportActive: true,
passportTitle : "Event 2",
passportDates: "October 20 - November 3, 2019",
venues: [
Venue (
title: "Bavaria Holiday Kitchen",
venueArea: "Germany Pavilion",
venueItems: [
venueItem (
title: "Potato Dumpling",
productDescription: "Potato Dumpling with Mushroom Sauce",
productPrice: 0.00,
productType: "Food",
newStatus: false,
diningPlan: false,
kidFriendly: true,
vegetarian: false,
glutenFree: false,
featuredProduct: false,
containsAlcohol: false
)
] // End VenueItems
) // End Venue
] // End Venues
)// End Individual Passport
] // End Return
}
}
PassportsView.swift
PassportsView.swift
import SwiftUI
struct PassportsView: View {
var model = Passports.all()
var body: some View {
NavigationView {
ForEach(self.model) { item in
NavigationLink (destination: PassportDetails(passportTitle: item.passportTitle, venues: item.venues, venueProd: []) ) {
HStack {
VStack(alignment: .leading) {
Text(item.passport[0].passportTitle)
.fontWeight(.semibold)
.foregroundColor(Color.white)
Text(item.passport[0].passportDates)
.foregroundColor(Color.white)
}.frame(width: 400, height: 120)
.background(Color("wPurple"))
.cornerRadius(6)
}
}.padding(.horizontal)
}
}
}
}
PassportDetails.swift
PassportDetails.swift
struct PassportDetails: View {
var passportTitle: String
var venues: [Venue]
var venueProd: [venueItem]
var body: some View {
List {
ForEach(self.venues) { gc in
Section(header: Text(gc.title)) {
ForEach(gc.venueItems, id: \.title) { gi in
GeometryReader { geometry in
VStack(alignment: .leading) {
HStack {
Text(gi.title)
.frame(width: geometry.size.width / 1.5, alignment: .leading)
.fixedSize(horizontal: false, vertical: true)
.padding(.top, 10)
Spacer()
Text("$\(gi.productPrice, specifier: "%.2f")")
.multilineTextAlignment(.trailing)
}.padding(.top, 8)
HStack {
Text(gi.productDescription)
.font(.footnote)
.foregroundColor(Color.gray)
.frame(width: geometry.size.width / 1.5, alignment: .leading)
.fixedSize(horizontal: false, vertical: true)
.padding(.bottom, 8)
Spacer()
}.padding(.bottom, 8)
}
}.padding(.vertical)
}
}
}
}.listStyle(GroupedListStyle())
.navigationBarTitle(Text(passportTitle), displayMode: .inline)
}
}
显然Text(item.passport[0].passportTitle)"将显示数组中的第一项,但我想在顶部数组中显示所有passportTitles和passportDates,并将信息传递给使用 NavigationLink 的详细信息视图.
So obviously "Text(item.passport[0].passportTitle)" is going to show the first item in the array, but I want to display all passportTitles and passportDates in the top array as well as passing the information on to the details view using the NavigationLink.
推荐答案
根据您的描述,您需要一个两级数据模型和视图层次结构:
Based on your description, you want a two level data model and view hierarchy:
- 事件列表(由
Passport
结构表示) - 每个活动的场地列表(由
Venue
结构表示)
- A list of events (represented by the
Passport
struct) - A list of venues for each event (represented by the
Venue
struct)
您当前的数据模型是三级(Passports
包含 Passport
包含 Venue
).
Your current data model is three level (Passports
containing Passport
containing Venue
).
如果我们移除无关的 Passports
结构,我们可以清理您的静态 .all()
函数和 PassportsView
结构.
If we remove the extraneous Passports
struct, we can clean up your static .all()
function and PassportsView
struct.
extension Passport {
static func all() -> [Passport] {
return [
Passport (
id: 1001,
passportPremium: false,
passportActive: true,
passportTitle : "Wine Festival",
passportDates: "October 20 - November 3, 2020",
venues: [
Venue (
title: "Bavaria Holiday Kitchen",
venueArea: "Germany Pavilion",
venueItems: [
venueItem (
title: "Potato Dumpling",
productDescription: "Potato Dumpling with Mushroom Sauce",
productPrice: 0.00,
productType: "Food",
newStatus: false,
diningPlan: false,
kidFriendly: true,
vegetarian: false,
glutenFree: false,
featuredProduct: false,
containsAlcohol: false
)
])
])
]
}
}
这是更新后的视图:
struct PassportsView: View {
var model = Passport.all()
var body: some View {
NavigationView {
ForEach(self.model) { passport in
NavigationLink (destination: PassportDetails(passportTitle: passport.passportTitle, venues: passport.venues, venueProd: []) ) {
HStack {
VStack(alignment: .leading) {
Text(passport.passportTitle)
.fontWeight(.semibold)
.foregroundColor(Color.white)
Text(passport.passportDates)
.foregroundColor(Color.white)
}.frame(width: 400, height: 120)
.background(Color("wPurple"))
.cornerRadius(6)
}
}.padding(.horizontal)
}
}
}
}
这篇关于SwiftUI - 列出嵌套数组中的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!