IceCream Store App Project

How do I change the data model of View A from View B? For instance, I have an App that uses multiple views.

I have a ForEach list of Buttons representing different types of Ice Cream and would like to use these buttons to change View B (model data).
What kind of tool should I look into trying?

@Davu

Hi David,

Can you show the code you have tried so far? Is the screen shot from your App so far or is it just an example of what you want to create?

Heres my Github Link to make it easier:
Github Link

View A

struct FeatureHorizontalView: View {
    @EnvironmentObject var model: IceCreamViewModel
    var arrayOfString = ["Hey"]
    
    var body: some View {
        VStack {
            GeometryReader { geo in
                
                ScrollView(.horizontal) {
                
                    HStack(spacing: 25) {
                    
                        ForEach(model.icecreams) { item in
                            ZStack {
                                Rectangle()
                                    .foregroundColor(Color("Celadon"))
                                VStack {
                                    Image(systemName: "sun.min")
                                        .font(.system(size: geo.size.width/4))
                                        .foregroundColor(Color("Thulian pink"))
                                        .padding(.bottom)
                                    Text(item.name)
                                        .font(.largeTitle)
                                    Text("$ \(String(format: "%.2f", item.available.price))")
                                        .font(.title)
                                        .bold()
                                        
                                }
                            }
                            .cornerRadius(30)
                            .frame(width: geo.size.width / 1.6, height: 380)
                        }
                    }
                }.scrollIndicators(.hidden)
            }
        }
    }
}

View B

struct FeatureHorizontalView: View {
    @EnvironmentObject var model: IceCreamViewModel
    var arrayOfString = ["Hey"]
    
    var body: some View {
        VStack {
            GeometryReader { geo in
                
                ScrollView(.horizontal) {
                
                    HStack(spacing: 25) {
                    
                        ForEach(model.icecreams) { item in
                            ZStack {
                                Rectangle()
                                    .foregroundColor(Color("Celadon"))
                                VStack {
                                    Image(systemName: "sun.min")
                                        .font(.system(size: geo.size.width/4))
                                        .foregroundColor(Color("Thulian pink"))
                                        .padding(.bottom)
                                    Text(item.name)
                                        .font(.largeTitle)
                                    Text("$ \(String(format: "%.2f", item.available.price))")
                                        .font(.title)
                                        .bold()
                                        
                                }
                            }
                            .cornerRadius(30)
                            .frame(width: geo.size.width / 1.6, height: 380)
                        }
                    }
                }.scrollIndicators(.hidden)
            }
        }
    }
}

OK I have the code and it runs although I have been lazy and not updated to Ventura (not that it matters in this case).

Can you clarify what you mean by “Change View B”? Do you mean change the options listed in View B?

Yes, View A is suppose to be the IceCream Catergory List. So popsicle, rolled etc. Then based on what’s selected View B changes to the different flavors related to the selection.


This is the design I’m following.

You pasted FeatureHorizontalView for both view A and B?
You have an iceCreamViewModel, you can use that in both views.
Or pass a binding from one view to another.

Also PS, I edited your post with the code.
Surround your code with 3 backticks at the beginning and end to format it properly

OK so essentially I take it that you want to filter the complete list of available categories you might have in your json code (or database for that matter) to just those in that selected category?

I have assumed Yes to the above so here is a copy of your project updated. Let me know if this is along the lines of what you were thinking. The code changes I made need a bit of refactoring to make it more efficient but you can see that it works.

When you download it, make sure that you save it somewhere different to your current version to avoid overwriting your version.

1 Like

Awesome! I don’t fully understand this yet but thank you for your effort.

Here’s info about State, Binding and ObservableObject and Publshed property wrappers that may help explain how they work and why that’s what I suggested

1 Like

Youtube Video Explanation

I created this video explaining what I’m trying to do. I hope this does it.

I’ll watch it now.

@Davu

Hi David,

Did you want to search on either name and/or available.flavour using the searchBar?

@Davu

Hi David,

This version enables you to search not only on name but also on available.flavor using the searchBar field. It converts the text you type in to lower case and also the field it compares against to lower case so that no matter what you type in, it will search correctly.

Revised code:

How select and use just the first flavor from this json:

[
    {
        "id": 1,
        "name": "Gelato",
        "image": "galato-icon",
        "available": {
            "id": 1,
            "flavor":
            {
                "choice1": "Dark Chocolate",
                "choice2": "Pistachio",
                "choice3": "Raspberries",
                "choice4": "Lemon",
                "choice5": "Tiramisu"
            },
            "images": [
                "chocolate gelato",
                "pistachio gelato",
                "raspberry gelato",
                "lemon gelato",
                "tiramisu gelato"
            ],
            "price": 5.49,
            "description": "Italian Ice Cream, that's made with whole milk, rather than cream. This difference enhances the flavors and puts a smile on your face."

        }
    },
    {
        "id": 2,
        "name": "Rolled",
        "image": "rolled-icon",
        "available": {
            "id": 2,
            "flavor":
            {
                "choice1": "Paan King",
                "choice2": "Strawberry Banana",
                "choice3": "Mint Chocolate Chip",
                "choice4": "Brownie",
                "choice5": "Salty, Sweet Caramel"
            },
            "images": [
                "paan rolled",
                "strawberry rolled",
                "mint rolled",
                "brownie rolled",
                "caramel rolled"
            ],
            "price": 8.99,
            "description": "Italian Ice Cream, that's made with whole milk, rather than cream. This difference enhances the flavors and puts a smile on your face."

        }
    },
    {
        "id": 3,
        "name": "Ice Popsicle",
        "image": "popsicle-icon",
        "available": {
            "id": 3,
            "flavor":
            {
                "choice1": "Banana",
                "choice2": "Cherry",
                "choice3": "FireCracker",
                "choice4": "Fudge",
                "choice5": "Grape"
            },
            "images": [
                "banana popsicle",
                "cherry popsicle",
                "firecracker popsicle",
                "fudge popsicle",
                "grape popsicle"
            ],
            "price": 2.48,
            "description": "Italian Ice Cream, that's made with whole milk, rather than cream. This difference enhances the flavors and puts a smile on your face."

        }
    },
    {
        "id": 4,
        "name": "Soft Servce",
        "image": "soft-icon",
        "available": {
            "id": 4,
            "flavor":
            {
                "choice1": "Chocolate",
                "choice2": "Vanilla",
                "choice3": "Strawberry",
                "choice4": "Cookies and Cream",
                "choice5": "Mint Chocolate Chip"
            },
            "images": [
                "chocolate soft",
                "vanilla soft",
                "strawberry soft",
                "cookies soft",
                "mint soft"
            ],
            "price": 3.39,
            "description": "Italian Ice Crea, that's made with whole milk, rather than cream. This difference enhances the flavors and puts a smile on your face."

        }
    },
    {
        "id": 5,
        "name": "Frozen Yogurt",
        "image": "yogurt-icon",
        "available": {
            "id": 5,
            "flavor":
            {
                "choice1": "Vanilla",
                "choice2": "Chocolate",
                "choice3": "Strawberry",
                "choice4": "Cookies and Cream",
                "choice5": "Banana"
            },
            "images": [
                "vanilla yogurt",
                "chocolate yogurt",
                "strawberry yogurt",
                "cookies yogurt",
                "banana yogurt"
            ],
            "price": 5.69,
            "description": "Italian Ice Crea, that's made with whole milk, rather than cream. This difference enhances the flavors and puts a smile on your face."

        }
    },
    {
        "id": 6,
        "name": "Mochi",
        "image": "mochi",
        "available": {
            "id": 6,
            "flavor":
            {
                "choice1": "Red Bean",
                "choice2": "Chocolate and Vanilla",
                "choice3": "Strawberry",
                "choice4": "Tiramisu",
                "choice5": "Green Tea"
            },
            "images": [
                "red bean mochi",
                "chocolate mochi",
                "strawberry mochi",
                "tiramisu mochi",
                "greentea mochi"
            ],
            "price": 4.97,
            "description": "Bite into the center of Mmmm. Made with real fruit, and bursting with sweet bits."

        }
    }
]

So that I can fill in list of views with the data?

This is what I’ve tried:

ForEach(model.icecreams) { item in
   Text(item.available.flavor.choice1)
}

If I try to use a index “[0]” it wont work.

If you were to have left your json code as it was, ie

    {
        "id": 1,
        "name": "Gelato",
        "image": "galato-icon",
        "available": {
            "id": 1,
            "flavor": 
            [ 
                "Dark Chocolate", 
                "Pistachio",
                "Raspberries",
                "Lemon",
                "Tiramisu"
            ],
            "images":
            [
                "chocolate gelato",
                "pistachio gelato",
                "raspberry gelato",
                "lemon gelato",
                "tiramisu gelato"
            ],
            "price": 5.49,
            "description": "Italian Ice Cream, that's made with whole milk, rather than cream. This difference enhances the flavors and puts a smile on your face."

        }
    },

then what you could have done in that example code above:

ForEach(model.icecreams) { item in
   Text(item.available.flavor.first ?? "") // first retrieves an Optional
}

and the output in the FeatureHorizontalView could be like these example screenshots using your project: