goBack fails to dismiss multiple views correctly.
andrewjmeier opened this issue · 1 comments
andrewjmeier commented
Bug description
[//]: # Using goBack
to navigate back to a previous screen doesn't dismiss all of the views when each view is presented modally.
Steps to reproduce
[//]: # Open a series of at least 3 modal views and then try to navigate back to the original view. One modal view will remain.
struct RootView: View {
var body: some View {
let dataSource = Navigator.Datasource(root: MainScreen())
let navigator = Navigator(dataSource: dataSource)
return Root(dataSource: dataSource, navigator: navigator, pathBuilder: MainScreen.Builder())
}
}
struct MainScreen: Screen {
var presentationStyle: ScreenPresentationStyle = .push
struct Builder: NavigationTree {
var builder: some PathBuilder {
Screen(
content: { (_: MainScreen) in MainView() },
nesting: { ModalScreen.Builder().eraseCircularNavigationPath() }
)
}
}
}
struct MainView: View {
@Environment(\.navigator) private var navigator
@Environment(\.currentScreenID) private var currentScreenID
var body: some View {
VStack {
Button {
navigator.go(to: ModalScreen(viewCount: 1, onDismiss: {
print(currentScreenID)
navigator.goBack(to: currentScreenID)
}), on: currentScreenID)
} label: {
Text("Show new view")
}
}
}
}
struct ModalScreen: Screen {
var presentationStyle: ScreenPresentationStyle = .sheet(allowsPush: true)
var viewCount: Int
var onDismiss: () -> Void
struct Builder: NavigationTree {
var builder: some PathBuilder {
Screen(
content: { (screen: ModalScreen) in ModalView(viewCount: screen.viewCount, onDismiss: screen.onDismiss) },
nesting: { ModalScreen.Builder().eraseCircularNavigationPath() }
)
}
}
}
extension ModalScreen: Equatable {
static func == (lhs: ModalScreen, rhs: ModalScreen) -> Bool {
return lhs.viewCount == rhs.viewCount
}
}
extension ModalScreen: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(viewCount)
}
}
struct ModalView: View {
@Environment(\.navigator) private var navigator
@Environment(\.currentScreenID) private var currentScreenID
var viewCount: Int
var onDismiss: () -> Void
var body: some View {
VStack {
Text("View \(viewCount)")
Button {
navigator.go(to: ModalScreen(viewCount: viewCount + 1, onDismiss: onDismiss), on: currentScreenID)
} label: {
Text("Show new view")
}
Button {
onDismiss()
} label: {
Text("dismiss all views")
}
}
}
}
Expected behavior
[//]: I would expect the original screen to be fully visible and all of the modal views to be dismissed.
Screenshots
Environment
- Xcode 12.5
- Swift 5.4
- iOS 14
ohitsdaniel commented
Hm, interesting. I will look into this. 🧐