1

First Dabble in SwiftUI, I've managed to get the below code working such that when I press a button, it will show a "selected" state and add the selected sports into an array. (and remove from the array if "deselected")

However, I can't figure out how to initialise the sportsArray with ALL values within the enum HelperIntervalsIcu.icuActivityType.allCases if it is initially empty.

I tried to put in

if sportsArray.isEmpty {
  HelperIntervalsIcu.icuActivityType.allCases.forEach {
  sportsArray.append($0.rawvalue)
} 

but Xcode keeps telling me type() cannot conform to View or things along those lines

struct selectSports: View {
  @State private var sportsArray = [String]()
   
  var body: some View {

    ScrollView(.horizontal, showsIndicators: false) {
      HStack {
        // https://stackoverflow.com/a/69455949/14414215
        ForEach(Array(HelperIntervalsIcu.icuActivityType.allCases), id:\.rawValue) { sport in
          Button(action: {
            addSports(sport: sport.rawValue)
          }) {
            HStack {
              Image(getSportsIcon(sport: sport.rawValue))
                .selectedSportsImageStyle(sportsArray: sportsArray, sport: sport.rawValue)
              Text(sport.rawValue)
            }
          }
          .buttonStyle(SelectedSportButtonStyle(sportsArray: sportsArray, sport: sport.rawValue))
        }
      }
    }
  }
  
  
  
  struct SelectedSportButtonStyle: ButtonStyle {
    var sportsArray: [String]
    var sport: String
    
    var selectedSport : Bool {
      if sportsArray.contains(sport) {
        return true
      } else {
        return false
      }
    }

    func makeBody(configuration: Self.Configuration) -> some View {
      configuration.label
        .font(selectedSport ? Font.subheadline.bold() : Font.subheadline)
        .aspectRatio(contentMode: .fit)
        .foregroundColor(selectedSport ? Color.orange : Color(UIColor.label))
        .padding([.leading, .trailing], 15)
        .padding([.top, .bottom],10)
        .overlay(
          RoundedRectangle(cornerRadius: 5.0)
            .stroke(lineWidth: 2.0)
            .foregroundColor(selectedSport ? Color.orange : Color.gray)
        )
        .offset(x: 10, y: 0)
    }
  }
  
  func addSports(sport: String) {
    if sportsArray.contains(sport) {
      let sportsIndex = sportsArray.firstIndex(where: { $0 == sport })
      sportsArray.remove(at: sportsIndex!)
    } else {
      sportsArray.append(sport)
    }
    print("Selected Sports:\(sportsArray)")
  }
}

No Sports Selected (in this case sportsArray is empty and thus the default state which I would like have would be to have ALL sports Pre-selected) enter image description here

2 Sports Selected

enter image description here

1 Answer 1

2

I assume you wanted to do that in onAppear, like

struct selectSports: View {
  @State private var sportsArray = [String]()
   
  var body: some View {

    ScrollView(.horizontal, showsIndicators: false) {
       // .. other code
    }
    .onAppear {
       if sportsArray.isEmpty {    // << here !!
          HelperIntervalsIcu.icuActivityType.allCases.forEach {
             sportsArray.append($0.rawvalue)
          }
       } 
    }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

onAppear and onDisappear is the equivalent of UIKit's viewWillAppear which was exactly what I wanted/needed.

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.