Ben O
Ben O

Reputation: 238

How to use if statement with struct in SwiftUI?

I am trying to use an if statement with a bool value in a struct to then see if a content view should be shown using that data. I keep getting the error "Ambiguous reference to member 'indices'" but I know this is not the actual problem it is just swiftUI saying there's an error on the forEach when it is the thing inside the forEach. This is the struct definition where needsToBeDeleted is false by default because it should be shown when first created

import Foundation

struct SEvent {
    var eventName:String;
    var timeSpent:String;
    var timeStarted:Date;
    var lastStarted:Date?;
    var needsToBeDeleted = false;
}

and this is the piece where I am iterating over an array of the events

ForEach(arrayOfEvents.indices, id: \.self) { index in
  if !self.arrayOfEvents[index].needsToBeDeleted {
     EventContentView(eventName: self.arrayOfEvents[index].eventName, timeSpent: 
     self.arrayOfEvents[index].timeSpent, shouldDelete: 
     self.$arrayOfEvents[index].needsToBeDeleted)
  }

}

Also this is the array declaration if that helps

@State private var arrayOfEvents = [SEvent]();

Edit:

This is the event content view code

import SwiftUI

struct EventContentView: View {
    var eventName:String;
    var timeSpent:String;

    var startStop = ["Start", "Stop"];
    @State var deleteTrigger = false;
    var buttonColor = [Color.blue, Color.yellow]
    @State var i = 0;
    @Binding var shouldDelete:Bool;
    var body: some View {

        VStack{
            VStack{
                Text("\(eventName)")
                    .frame(minWidth: 0, idealWidth: 150, maxWidth: 200, minHeight: 0, idealHeight: 50, maxHeight: 75, alignment: .center)

                Text("\(timeSpent)")
                    .frame(minWidth: 0, idealWidth: 150, maxWidth: 200, minHeight: 0, idealHeight: 50, maxHeight: 100, alignment: .leading)
                if !deleteTrigger {
                HStack {
                Button(action: {
                    if self.i == 0{

                        self.i = 1
                    }
                    else if self.i == 1 {
                        self.i = 0
                    }

                }) {
                    Text(startStop[i])
                }

                .foregroundColor(buttonColor[i])
                .frame(minWidth: 0, idealWidth: 50, maxWidth: 100, minHeight: 0, idealHeight: 20, maxHeight: 40, alignment: .leading)
                    Button(action: {
                        self.deleteTrigger = true;
                    }) {
                       Text("Delete")
                    }
                    .foregroundColor(.red)
                    .animation(.interactiveSpring(response: 1, dampingFraction: 0.5, blendDuration: 1.5))
                    .frame(minWidth: 0, idealWidth: 50, maxWidth: 100, minHeight: 0, idealHeight: 20, maxHeight: 40, alignment: .trailing)
                }

            }
                else{
                    HStack {
                       Button(action: {
                        self.shouldDelete = true
                       }) {
                           Text("Delete")
                       }
                       .foregroundColor(.red)
                       .frame(minWidth: 0, idealWidth: 50, maxWidth: 100, minHeight: 0, idealHeight: 20, maxHeight: 40, alignment: .leading)
                           Button(action: {
                            self.deleteTrigger = false;
                           }) {
                              Text("Don't Delete")

                           }
                           .foregroundColor(.green)
                            .animation(.easeInOut)
                        .frame(minWidth: 0, idealWidth: 50, maxWidth: 100, minHeight: 0, idealHeight: 20, maxHeight: 40, alignment: .trailing)
                       }

                }
            }
            .frame(minWidth: 0, maxWidth: 200, minHeight: 20, idealHeight: 30, maxHeight: 150, alignment: .center)
        }
        .padding()
        .overlay(
        RoundedRectangle(cornerRadius: 5.0)
            .stroke(Color.black, lineWidth: 1)
            .shadow(radius: 5)
            )
        .padding()

    }
}

and the specific part that deletes the view is this button where it changes the binding variable shouldDelete to true which changes the needsToBeDeleted element of the SEvent Struct in arrayOfEvents to true

Button(action: {
 self.shouldDelete = true
}) 
{
   Text("Delete")
}

Upvotes: 0

Views: 1823

Answers (1)

Sorin Lica
Sorin Lica

Reputation: 7656

You can use it like this

var body: some View {
        ForEach(arrayOfEvents.indices, id: \.self) { index -> AnyView in
            if !self.arrayOfEvents[index].needsToBeDeleted {
                return AnyView(EventContentView(eventName: self.arrayOfEvents[index].eventName, timeSpent:
                    self.arrayOfEvents[index].timeSpent, shouldDelete:
                    self.$arrayOfEvents[index].needsToBeDeleted))

            } else {
                return AnyView(EmptyView())
            }

        }

    }

Upvotes: 1

Related Questions