I have an Exercise Model that has can belong to a Workout or it can be standalone:
@Model
class Exercise {
var id: UUID
var exerciseName: ExerciseName
@Relationship(deleteRule: .cascade)
var sets: [Set]? //When an Exercise gets Deleted all Sets associated need to get deleted
var date: Date
var workout: Workout? //it can belong to a work but it doesnt have to
init(id: UUID, exerciseName: ExerciseName, date: Date) {
self.id = id
self.exerciseName = exerciseName
self.date = date
}
}
and then I have a Workout which should be initialized as soon as the user Navigates to AddWorkoutView so that it can be passed to the ExerciseView:
@Model
class Workout {
var id: UUID
var name: String?
@Relationship(deleteRule: .cascade) //when deleting a workout you delete all exericses that happened during that workout
var exercises: [Exercise]?
var date: Date
init(id: UUID, date: Date) {
self.id = id
self.date = date
}
}
How do I initialize a Workout when the users navigates to this page so that I can pass said workout to the sheet?
import SwiftUI
import SwiftData
struct AddWorkoutView: View {
@Environment(.modelContext) var modelContext
@Query var exercises: [Exercise]
@State private var workoutName: String = ""
@State private var showExercieSheet = false
//var workout: Workout
var body: some View {
VStack() {
VStack(spacing: 60) {
VStack {
HStack{
Text("Create New Workout")
.font(.title)
.fontWeight(.semibold)
Spacer()
}
.padding(.leading)
TextField("Enter workout name",text: $workoutName)
.textFieldStyle(.roundedBorder)
.font(.title3)
.padding()
}
if(exercises.isEmpty) {
//chat why does this VStack have padding that i didnt add
VStack(alignment: .leading ,spacing: 10){
Text("Exercises")
.font(.headline)
.foregroundStyle(.gray)
Text("Press Add Exercise to create your first exercise")
.foregroundStyle(.gray)
.font(.subheadline)
}
}
else
{
List(exercises) { exercise in
Text(exercise.exerciseName.name)
}
}
Button {
showExercieSheet = true
} label: {
Text("Add Exercise")
.font(.headline)
.foregroundStyle(.white)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color.blue)
.clipShape(RoundedRectangle(cornerRadius: 16))
.shadow(radius: 2)
.padding()
}
Spacer()
}
.toolbar {
Button {
//Save the Content
} label: {
Text("Save")
.font(.headline)
.underline()
.foregroundStyle(.blue)
.fontWeight(.semibold)
.padding()
}
}
.sheet(isPresented: $showExercieSheet) {
AddExerciseView()
.presentationDragIndicator(.visible)
}
}
}
}
this is the view that the sheet presents:
import Foundation
import SwiftUI
import SwiftData
struct AddExerciseView: View {
@Environment(.modelContext) var modelContext
@Query var exercisesNames: [ExerciseName]
@State private var showNameInput = false
@State private var exerciseName = ""
@State private var selection: ExerciseName?
@Environment(.dismiss) private var dismiss
// private var workout: Workout
var body: some View {
VStack {
HStack{
Spacer()
Button {
//more to come
showNameInput.toggle()
} label: {
showNameInput ?
Image(systemName: "minus.circle")
.resizable()
.frame(width: 24, height: 24)
:
Image(systemName: "plus.circle")
.resizable()
.frame(width: 24, height: 24)
}
.padding(28)
}
if(showNameInput == true) {
HStack{
TextField("Enter Exercise Name", text: $exerciseName)
.frame(height: 35)
.textFieldStyle(.roundedBorder)
.font(.title3)
.padding(.leading)
Button {
//database operation adding exerciseName to ExerciseName model
if (!exerciseName.isEmpty) {
let newExeriseName = ExerciseName(name: exerciseName)
modelContext.insert(newExeriseName)
showNameInput.toggle()
}
}label: {
Text("Add")
}
.font(.headline)
.foregroundStyle(.white)
.frame(height: 35)
.frame(width: 70)
.background(Color.blue)
.clipShape(RoundedRectangle(cornerRadius: 8))
.shadow(radius: 1)
.padding()
}
}
List(exercisesNames,id: .self, selection: $selection) { exercisename in
Text(exercisename.name)
}
Button {
//check If selection isnt empty than create an Exercise with this(selection) as the ExerciseName
//and dismiss this sheet
if(selection != nil) {
let newExercise = Exercise(id: UUID(),exerciseName: selection!, date: Date.now)
modelContext.insert(newExercise)
print("inserted: (newExercise.exerciseName.name)")
dismiss()
}
} label: {
Text("Done")
.font(.headline)
.foregroundStyle(.white)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color.blue)
.clipShape(RoundedRectangle(cornerRadius: 16))
.shadow(radius: 2)
.padding()
}
}
.onAppear {
if exercisesNames.isEmpty {
showNameInput=true
}
}
}
}
#Preview {
AddExerciseView()
}
So far I have tried creating a Workout object and inserting it into the modelContext inside an OnAppear modifier but it was not successful.