I am having bother creating transitions that correctly emulate iOS navigation transitions. Totally different transitions ought to play relying on whether or not the person is navigating “ahead” or “backward”, however it looks like the view inside my change assertion is not getting the latest model of the state variable being up to date. This ends in unusual conduct – after “going” ahead, backward, and ahead once more, the view that is being eliminated is not studying the latest worth of my boolean variable and performs the outdated transition as an alternative.
I perceive why the issue is happening, however it’s extraordinarily irritating as I’ve spent the final two hours attempting to repair this situation with no success. I’ve connected code and a GIF beneath. Thanks!
ContentView.swift
import SwiftUI
enum NavigationViewType {
case firstView, secondView, thirdView
}
struct ContentView: View {
@State non-public var currentView: NavigationViewType = .firstView
@State non-public var isReverse = false
var physique: some View {
VStack {
change currentView {
case .firstView:
FirstView(nextView: goToNextView, goBack: goBack, isReverse: $isReverse)
.transition(isReverse ? .reverseSlide : .slide)
case .secondView:
SecondView(nextView: goToNextView, goBack: goBack, isReverse: $isReverse)
.transition(isReverse ? .reverseSlide : .slide)
case .thirdView:
ThirdView(nextView: goToNextView, goBack: goBack, isReverse: $isReverse)
.transition(isReverse ? .reverseSlide : .slide)
}
}
.animation(.default)
}
func goToNextView() {
withAnimation {
isReverse = false
change currentView {
case .firstView:
currentView = .secondView
case .secondView:
currentView = .thirdView
case .thirdView:
currentView = .firstView
}
}
}
func goBack() {
withAnimation {
isReverse = true
change currentView {
case .firstView:
currentView = .thirdView
case .secondView:
currentView = .firstView
case .thirdView:
currentView = .secondView
}
}
}
}
struct FirstView: View {
var nextView: () -> Void
var goBack: () -> Void
@Binding var isReverse: Bool
var physique: some View {
VStack {
Textual content("First View")
Button("Subsequent") {
nextView()
}
Button("Again") {
isReverse = true
goBack()
}
}
.body(maxWidth: .infinity, maxHeight: .infinity)
.background(Shade.blue)
}
}
struct SecondView: View {
var nextView: () -> Void
var goBack: () -> Void
@Binding var isReverse: Bool
var physique: some View {
VStack {
Textual content("Second View")
Button("Subsequent") {
nextView()
}
Button("Again") {
isReverse = true
goBack()
}
}
.body(maxWidth: .infinity, maxHeight: .infinity)
.background(Shade.inexperienced)
}
}
struct ThirdView: View {
var nextView: () -> Void
var goBack: () -> Void
@Binding var isReverse: Bool
var physique: some View {
VStack {
Textual content("Third View")
Button("Subsequent") {
nextView()
}
Button("Again") {
isReverse = true
goBack()
}
}
.body(maxWidth: .infinity, maxHeight: .infinity)
.background(Shade.yellow)
}
}
extension AnyTransition {
static var slide: AnyTransition {
let transition = AnyTransition.uneven(
insertion: AnyTransition.transfer(edge: .trailing),
removing: AnyTransition.transfer(edge: .main)
)
return transition
}
static var reverseSlide: AnyTransition {
let transition = AnyTransition.uneven(
insertion: AnyTransition.transfer(edge: .main),
removing: AnyTransition.transfer(edge: .trailing)
)
return transition
}
}