Hello everyone I tried to create a selectable item in SwiftUI like the image bellow, but I don't know how to do that when i touch on each item change the color and color font, and after that add this item to a new state, that would be a list,this is my code and i'm using a library in order to organice the items.
This is my item's code
import SwiftUI
struct SportItem: View {
@EnvironmentObject var modelData: ModelData
var sport: Sport
var backgroundColor: Color = Color(red: 103, green: 80, blue: 164)
var body: some View {
HStack{
Text(sport.emoji)
Text(" "+sport.name)
.bold()
}.font(.system(size: 14))
.padding(8)
// .background(backgroundColor)
.background(Color(red: 0.403921568627451, green: 0.3137254901960784, blue: 0.6431372549019608))
.foregroundColor(.white)
.cornerRadius(15)
.shadow(color: Color.black, radius: 3)
}
}
struct SportItem_Previews: PreviewProvider {
static var modelData = ModelData()
static var previews: some View {
SportItem(sport: modelData.sports[6])
.environmentObject(modelData)
}
}
I try to create a grid, the goal is this file to create the state variable a can choose sport I wanted
import SwiftUI
import WrappingStack
struct SelectSport: View {
var event: Event
@State private var eventForm = Event(id: Int(), name: "", place: "", description: "",date: Date(), beginTime: 1, endTime: 2, img: "", sports: Set<Sport>())
@State var selectedSports: Set<Sport> = Set<Sport>()
@EnvironmentObject var modelData: ModelData
var sportsList: [Sport] { modelData.sports }
var body: some View {
VStack{
Text("Which sports do you want to include?")
Text(event.name)
WrappingHStack {
ForEach(sportsList){
sport in
SportItem(sport: sport)
.padding(4)
}
}
}
.navigationTitle("Select Sports")
.navigationBarItems(trailing:
NavigationLink(destination:DatePickerEvent(event: Event(id: 1, name: "", place: "", description: "", date: Date(), beginTime: 1, endTime: 1, img: "", sports: Set<Sport>() ))){
Text("Next")
}
)
}
}
struct SelectSport_Previews: PreviewProvider {
static var previews: some View {
SelectSport(event: Event(id: 1, name: "", place: "", description: "",date: Date(), beginTime: 1, endTime: 2, img: "", sports: Set<Sport>()))
.environmentObject(ModelData())
}
}
First, add an isSelected
property to SportItem
, and change how you draw the item depending on isSelected
. For example:
struct SportItem: View {
@EnvironmentObject var modelData: ModelData
var sport: Sport
var isSelected: Bool // <— ADD THIS
// CHANGE THIS
var backgroundColor: Color {
if isSelected { return Color.red }
else { return Color(red: 0.403921568627451, green: 0.3137254901960784, blue: 0.6431372549019608) }
}
var body: some View {
HStack{
Text(sport.emoji)
Text(" "+sport.name)
.bold()
}.font(.system(size: 14))
.padding(8)
.background(backgroundColor) // <- CHANGE THIS
.foregroundColor(.white)
.cornerRadius(15)
.shadow(color: Color.black, radius: 3)
}
}
Then, in SelectSport
, make two changes:
Pass the isSelected
property to SportItem
. The value to pass depends on whether selectedSports
contains sport
.
Add an .onTapGesture
modifier after SportItem
that toggles whether selectedSports
contains sport
.
For example:
SportItem(sport: sport, isSelected: selectedSports.contains(sport))
.onTapGesture {
selectedSports.formSymmetricDifference([sport])
}
.padding(4)