Context: I have encountered a problem while working with SwiftUI Transitions
. I have a FormView
containing 4 different Sub-Forms
. When the User presses the Next-Button
, the next Sub-Form View
is presented with a Transition
(.move -> right to left).
I also have a Back Button
. When the User presses this Button, the previous Sub-Form View
is shown, currently with the same Transition
(.move -> right to left). However, I'd like to reverse the Transition
in this case to (.move -> left to right).
Code
enum FormStep {
case step1, step2, step3, step4
}
struct CustomForm: View {
@State private var step: FormStep = .step1
var body: some View {
// This Button will change the step State to the previous step
Button(action: { withAnimation { previousStep() } } { Text("Previous") }
// This is the Right to Left Transition applied to subForm
subForm
.transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
// This Button will change the step State to the next step
Button(action: { withAnimation { nextStep() } } { Text("Next") }
}
@ViewBuilder private var subForm: some View {
switch medicationFormVM.step {
case .step1: StepOneSubForm()
case .step2: StepTwoSubForm()
case .step3: StepThreeSubForm()
case .step4: StepFourSubForm()
}
}
}
Question: As you can see, not matter whether you navigate back or forth, the Transition
will always be right to left
. How can I achieve my goal of changing the Transition
depending on which Button
got pressed?
CodePudding user response:
Here is an approach for you:
enum FormTransition {
case next, back
var value: AnyTransition {
switch self {
case .next:
return AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading))
case .back:
return AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing))
}
}
}
struct CustomForm: View {
@State private var step: FormStep = .step1
@State private var transition: AnyTransition = FormTransition.next.value
var body: some View {
Button(action: { transition = FormTransition.back.value; withAnimation { previousStep() } } { Text("Previous") })
subForm
.transition(transition)
Button(action: { transition = FormTransition.next.value; withAnimation { nextStep() } } { Text("Next") })
}
}