Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

goBack fails to dismiss multiple views correctly. #72

Open
andrewjmeier opened this issue May 14, 2021 · 1 comment
Open

goBack fails to dismiss multiple views correctly. #72

andrewjmeier opened this issue May 14, 2021 · 1 comment

Comments

@andrewjmeier
Copy link

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

[//]: Simulator Screen Recording - iPod touch (7th generation) - 2021-05-14 at 10 13 21

Environment

  • Xcode 12.5
  • Swift 5.4
  • iOS 14
@ohitsdaniel
Copy link
Contributor

Hm, interesting. I will look into this. 🧐

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants