I have created a message toast type alerts following Fancy Toast Messages
Then I created a view that loops through a json file of ingredients
[
{
"id" : 1,
"name": "Spicy Watermelon Mint Agua Fresca",
"headline": "A refreshing blend of fruity flavor with a blast of spice.",
"image": "Drink1",
"equipment": ["Blender", "Strainer"],
"servingsize": 4,
"drinkware": "Pitcher",
"preptime": 10,
"difficulty": 1.5,
"rating": 2,
"category": ["Agua Fresca"],
"ingredients": [
"2 cups cold water",
"2 cups watermelon (rind removed), seeded and chopped",
"2 tbsp granulated sugar",
"1 tbsp lime juice",
".25 cup mint leaves",
".5 jalapeño, roughly chopped",
"Ice cubes or crushed ice (optional)"
],
"instructions": [
"Add the ingredients into a blender.",
"Blend ingredients until mixture is smooth.",
"Pour mixture through a fine-mesh sieve into a large pitcher, forcing through most of the pulp.",
"Let chill before serving.",
"Serve and enjoy!"
],
"shoppinglist": [
"Watermelon",
"Granulated Sugar",
"Lime Juice",
"Mint Leaves",
"Jalapeño"
]
}
]
Data model
struct Drinks: Codable, Identifiable, Comparable {
static func < (lhs: Drinks, rhs: Drinks) -> Bool {
lhs.name < rhs.name
}
var id: Int
var name: String
var headline: String
var image: String
var equipment: [String]
var servingsize: Int
var drinkware: String
var preptime: Int
var difficulty: Double
var rating: Int
var category: [String]
var ingredients: [String]
var instructions: [String]
var shoppinglist: [String]
}
All is displaying and working correctly.
The issue resides in the view that showing this. I am adding a button that adds the item that is clicked on to a realm database. That aspect is working on a one to one relationship.
What is displaying or exhibiting undesired behavior is when you click on the plus sign its triggering the message alert for every button that is in the stack.
I am not sure how to separate them out to a 1x1 event with the button so after each click it only fires the event once instead of one time for each button that was added to the view for each item in the ingredients list.
Here is the view
import SwiftUI
struct DrinkDetailViewIngredients: View {
let drinks: Drinks
@State private var toast: MessageToast? = nil
var body: some View {
Spacer()
Text("INGREDIENTS")
.fontWeight(.bold)
.modifier(TitleModifier())
ForEach(drinks.ingredients, id: \.self) { item in
VStack(alignment: .leading, spacing: 2) {
HStack {
Text(item)
.lineLimit(nil)
.multilineTextAlignment(.leading)
.font(.system(.body, design: .serif))
.frame(minHeight: 50)
.padding(.leading)
.foregroundColor(.yellow)
Spacer()
Button {
toast = MessageToast(
type: .success,
title: "Item Added",
message: "Item Added to shopping list."
)
} label: {
Image(systemName: "plus")
.foregroundColor(.yellow)
.imageScale(.large)
}
.toastView(toast: $toast)
.buttonStyle(.borderless)
}
}
}
}
}
struct DrinkDetailViewIngredients_Previews: PreviewProvider {
static var previews: some View {
DrinkDetailViewIngredients(drinks: drinks[0])
}
}
This is what happens when you click the plus sign and the message alert is triggered.
CodePudding user response:
I figured out the solution to the issue. I embedded the ForEach Loop in a VStack and then moved the message alert to that VStack versus having the message alert on the button itself. Here is the final code.
import SwiftUI
struct DrinkDetailViewIngredients: View {
//MARK: - PROPERTIES
let drinks: Drinks
@State private var toast: MessageToast? = nil
//MARK: - FUNCTIONS
//MARK: - BODY
var body: some View {
// Ingredients
Spacer()
Text("INGREDIENTS")
.fontWeight(.bold)
.modifier(TitleModifier())
VStack {
ForEach(drinks.ingredients, id: \.self) { item in
VStack(alignment: .leading, spacing: 2) {
HStack {
Text(item)
.lineLimit(nil)
.multilineTextAlignment(.leading)
.font(.system(.body, design: .serif))
.frame(minHeight: 50)
.padding(.leading)
.foregroundColor(Color(.yellow)
Spacer()
VStack {
Button {
toast = MessageToast(type: .success, title: "Item Added", message: "Item Added to shopping list.")
} label: {
Image(systemName: "plus")
.foregroundColor(Color(.yellow))
.imageScale(.large)
} //:END OF BUTTON
.buttonStyle(.borderless)
} //:END OF VSTACK
} //:END OF HSTACK
} //: END OF VSTACK INGREDIENTS
}//: END OF LOOP INGREIDENTS
} //: END OF OUTTER VSTACK
.toastView(toast: $toast)
} //: END OF BODY
} //: END OF STRUCT
//MARK: - PREVIEW
struct DrinkDetailViewIngredients_Previews: PreviewProvider {
static var previews: some View {
DrinkDetailViewIngredients(drinks: drinks[0])
}
}