3

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.

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 (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

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

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)
}
}

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.

1 Answer 1

2

Based on your description, you want a two level data model and view hierarchy:

  1. A list of events (represented by the Passport struct)
  2. A list of venues for each event (represented by the Venue struct)

Your current data model is three level (Passports containing Passport containing Venue).

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
                            )
                    ])
            ])
        ]
    }
}

Here's the updated view:

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)
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.