I am trying to animate a view change using a transition. My goal is that the view slides in from the right or left and the old view slides out in the same direction just like in the Picker from my example. It's no problem to implement that for two views, because the first view always slides in and out from/to the left, so I can use the .move(edge: .leading) modifier. For the second view it's the same idea but mirrored.
The problem occurs if I have three or more views, the view(s) in the middle has/have to perform a different transition depending on the previous/next view index. So I wrote some code in an ObservableObject to specify how the animation should look. However, my code doesn't really work. If I move from one view to another, everything is fine. But if I go from the View 0 to View 1 to View 2 the animation from View 1 to View 2 is wrong (see GIF). After switching from View 2 back to View 1, the transition between 2 and 1 works (but now the transition between 0 and 1 is messed up again).
What am I doing wrong? Maybe there even are simpler ways to do something like this?
struct ContentView: View {
@ObservedObject var settings = Settings()
var body: some View {
VStack{
Spacer()
Picker("/numbers", selection: self.$settings.viewIndex.animation(.spring())) {
Text("View 0").tag(0)
Text("View 1").tag(1)
Text("View 2").tag(2)
}
.pickerStyle(SegmentedPickerStyle())
Spacer()
if(self.settings.viewIndex == 0){
ZStack{
Text("View 0").font(.largeTitle)
}.frame(width: UIScreen.main.bounds.width)
.transition(.move(edge: .leading))
}
if(self.settings.viewIndex == 1){
ZStack{
Text("View 1").font(.largeTitle)
}.frame(width: UIScreen.main.bounds.width)
.transition(.move(edge: self.settings.middleAnimationIsLeading ? .leading : .trailing))
}
if(self.settings.viewIndex == 2){
ZStack{
Text("View 2").font(.largeTitle)
}.frame(width: UIScreen.main.bounds.width)
.transition(.move(edge: .trailing))
}
Spacer()
}
}
}
class Settings: ObservableObject {
@Published var viewIndex = 1{
willSet(newValue){
//View 1 should move from and to right edge
if(viewIndex == 1 && newValue == 0 || viewIndex == 0 && newValue == 1){
middleAnimationIsLeading = false
}
//View 1 should move from and to left edge
if(viewIndex == 1 && newValue == 2 || viewIndex == 2 && newValue == 1){
middleAnimationIsLeading = true
}
}
}
@Published var middleAnimationIsLeading = false {
didSet {
print("is leading: \(middleAnimationIsLeading)")
}
}
}
