I'm working on a sequence of screens that should change on a button press and should slide in/out from right to left.
Everything is working nicely except the .slide
transition makes it move in from the leading edge and move out to the trailing edge. (from left to right)
I want to reverse the transition animation direction without changing what trailing/leading is (at least not in the whole context of the app).
I tried changing the transition to .move(edge: .trailing)
but then the views move in and out from the same direction.
import SwiftUI
struct ContentView: View {
enum screens {
case start, mid, final
}
@State var curScreen: screens = .start
func changeScreen() {
switch curScreen {
case .start:
curScreen = .mid
case .mid:
curScreen = .final
case .final:
return
}
}
var body: some View {
switch curScreen {
case .start:
ScreenView(callback: changeScreen, text: "Start")
.transition(.slide)
case .mid:
ScreenView(callback: changeScreen, text: "Mid")
.transition(.slide)
case .final:
ScreenView(callback: {}, text: "Final")
.transition(.slide)
}
}
}
struct ScreenView: View {
let callback: () -> ()
let text: String
var body: some View {
Text(text)
.padding()
.frame(maxWidth: .infinity)
.onTapGesture {
withAnimation(.default) {
callback()
}
}
}
}
CodePudding user response:
@Asperi has already answered my question, but it didn't show up on google or stackoverflow when I searched for it, so here again for the algorithm:
How to reverse the slide transition in SwiftUI:
Taken from the Apple Developer Documentation:
static var slide: AnyTransition
// A transition that inserts by moving in from the leading edge, and removes by moving out towards the trailing edge.
Which can also be written as:
AnyTransition.asymmetric(
insertion: .move(edge: .leading),
removal: .move(edge: .trailing)
)
So to reverse the animation just flip insertion
and removal
and put that in your transition ViewModifier.
Since I needed to use it a few times I made an extension to AnyTransition
so I can just call .transition(.backslide)
extension AnyTransition {
static var backslide: AnyTransition {
AnyTransition.asymmetric(
insertion: .move(edge: .trailing),
removal: .move(edge: .leading))}
}