Hi all - somewhat new to swift, but have been developing apps in the React Native world for a few years now.
I completed the iDine app project and have been making it my own by creating a workout logging app. I am running into an issue where I have a class Workout
that is comprised Exercise
s that have Set
s, and when rendering a workout I am iterating on each Set
. I want to be able to pass the Set
s weight
to a TextField
so that users can update this.
I have this working currently, but through a seemingly nasty way where I pass the entire workouts
array and access the correct exercise/set via indexing the arrays. This feels wrong. How can or should I pass the weight
and reps
of the Set
to my SetRow
view as a binding?
Below you will find my structs
enum ExerciseMovements: String, Codable {
case squat = "Squat"
case benchPress = "Bench Press"
case deadlift = "Deadlift"
}
struct Set: Codable, Equatable, Identifiable {
var id: UUID
var weight: String
var reps: String
}
struct Exercise: Equatable, Identifiable {
var id: UUID
var date: Date
var type: ExerciseMovements
var sets: [Set]
}
Below is how I am building out the WorkoutView
struct WorkoutDetailView: View {
@State private var workoutName = "New Workout"
@State private var exercises: [Exercise] = []
func addExercise() {
let exerciseToAdd = Exercise(id: UUID(), date: Date(), type: .benchPress, sets: [])
exercises.append(exerciseToAdd)
}
func addSet(exercise: Exercise) {
if let index = exercises.firstIndex(of: exercise) {
let setToAdd = Set(id: UUID(), weight: "0", reps: "0")
exercises[index].sets.append(setToAdd)
}
}
func saveExercise() {
print(exercises)
}
var body: some View {
ScrollView {
VStack {
ForEach(Array(exercises.enumerated()), id: \.offset) { exerciseIndex, exercise in
VStack {
HStack {
Text("Set")
Spacer()
Text("LBs")
Spacer()
Text("Reps")
}
ForEach(Array(exercise.sets.enumerated()), id: \.offset) { setIndex, set in
SetRow(exercises: $exercises, exerciseIndex: exerciseIndex, setIndex: setIndex)
}
.padding(.vertical)
.frame(maxWidth: .infinity)
Button("Add Set") {
addSet(exercise: exercise)
}
}
}
.padding()
Button("Add Exercise") {
addExercise()
}
}
.navigationTitle(workoutName)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
Button("Finish") {
saveExercise()
}
}
}
}
And below is the SetRow
struct SetRow: View {
@Binding var exercises: [Exercise];
var exerciseIndex: Int;
var setIndex: Int
var body: some View {
HStack {
Text("\(setIndex + 1)")
Spacer()
TextField(exercises[exerciseIndex].sets[setIndex].weight, text: $exercises[exerciseIndex].sets[setIndex].weight)
.keyboardType(.numberPad)
.frame(width: 50)
Spacer()
}
}
}