Search code examples
swiftswiftuitimer

SwiftUI-How to transition between text when a button is pressed


I am making an exercise app and I want to transition between different exercises without making many seperate views as I am also making a timer which will publish too many times if I did that. I want to make it so that when I click a button, it will transition all the text from exercise1 to exercise 2 then to exercise 3 and so on. I want to transition all these using the same button.

So far what I have done is created navigation paths to different views that contain the different exercises but the timer broke when I did that because I called it many times causing it to countdown too fast. I want to see if I can contain all the exercises inside 1 view and transition between them. So for example I want to transition from:

Text(exercisePlan.exercise.title) to Text(exercisePlan.exercise2.title) then to Text(exercisePlan.exercise3.title) all with a click of one button
import SwiftUI
import AVKit

struct ExerciseScreenView: View {
    @Binding var streaks: Streaks
    @Binding var timerStruct: TimerStruct
    var countdownTimer = 300
    @State var player = AVPlayer()
    var exercisePlan: ExercisePlan
    @Binding var navigationPath: NavigationPath
    
    func reset() {
        timerStruct.countdownTimer = 300
        timerStruct.timerRunning = false
    }
    
    var body: some View {
        VStack {
            Form {
                Section(header: Text("1st Exercise (Scroll down for exercise steps)")) {
                    Text(exercisePlan.exercise.title)
                        .font(.system(size: 35, weight: .medium))
                        .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
                }
                
                Section(header: Text("Video example")) {
                    VideoPlayer(player: exercisePlan.exercise.video)
                        .scaledToFit()
                        .frame(alignment: .center)
                        .cornerRadius(10)
                        .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
                }
                    Section(header: Text("Steps:")){
                        Text(exercisePlan.exercise.steps)
                            .font(.system(size: 20, weight: .regular))
                            .padding()
                            .frame(alignment: .center)
                    }
                }
                         
                    
                    
                    
            TimerView(streaks: $streaks, timerStruct: $timerStruct)
                        .padding(EdgeInsets(top: 0, leading: 0, bottom: 15, trailing: 0))
                    
                    Button {
                        navigationPath.append("ExerciseScreen2View")
                    } label: {
                        Text("Next exercise")
                            .padding()
                            .background((Color(red: 184/255, green: 243/255, blue: 255/255)))
                            .foregroundColor(.black)
                            .cornerRadius(10)
                            .navigationBarBackButtonHidden()
                    }
                    .padding(EdgeInsets(top: 0, leading: 10, bottom: 10, trailing: 10))
                    
                }
            }
        }

Solution

  • What you want to do is create an array of the Exercises. Pressing the button should increase an index to get the relevant plan to show in your view.

    Small code example:

    struct ExerciseScreenView: View {
        
        var exercises: [Exercise]
        @State var index: 0
    
        var body: some View {
            VStack {
                Text(exercises[index].title)
                Button {
                        if exercisePlan.count - 1 > index {
                            index += 1                        
                        } else {
                            // leave screen
                        }
                    } label: {
                        Text("Next exercise")
                    }
                }
            }
        }
    }
    

    This is a very basic example and can be improved by a lot, but it gives you a basic idea how to do it.