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

SwiftUI's native dismiss environment value does not work from fullscreen modal with navigation #86

Open
CorbinMontague opened this issue Oct 7, 2024 · 4 comments

Comments

@CorbinMontague
Copy link

There is a bug where attempting to use SwiftUI's native dismiss environment value does not work from a fullscreen modal presented with navigation: foo.presentCover(Screen.modalView, withNavigation: true). This bug is present in both the 0.8.1 and 0.8.2 versions (I haven't checked any other versions). Workaround is to use FlowPathNavigator or a reference to the FlowPath associated with the FlowStack because FlowStacks dismiss APIs still work as expected. See code example below:

import Foundation
import FlowStacks
import SwiftUI

public enum Screen {
    case modalView
}
extension Screen: Identifiable, Hashable {
    public var id: String {
        return String(reflecting: self)
    }
    
    public func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    public static func == (lhs: Screen, rhs: Screen) -> Bool {
        lhs.id == rhs.id
    }
}

struct ScreenViewBuilder {
    static func view(for screen: Screen) -> some View {
        switch screen {
        case .modalView:
            return ModalView()
        }
    }
}

struct ContentView: View {
    
    @State var path = FlowPath()
    var body: some View {
        FlowStack($path, withNavigation: true) {
            makeRootView()
                .flowDestination(for: Screen.self) { screen in
                    ScreenViewBuilder.view(for: screen)
                }
        }
    }
    
    @ViewBuilder private func makeRootView() -> some View {
        Button("Present ModalView with navigation") {
            path.presentCover(Screen.modalView, withNavigation: true)
        }
    }
}

struct ModalView: View {
    @Environment(\.dismiss) private var dismiss
    @EnvironmentObject var navigator: FlowPathNavigator
    
    var body: some View {
        Text("Modal View")
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Native Dismiss") {
                        dismiss() // does not work
                    }
                }
                
                ToolbarItem(placement: .topBarTrailing) {
                    Button("FlowStacks Dismiss") {
                        navigator.dismiss() // works
                        // navigator.goBack() // works
                    }
                }
            }
    }
}
@CorbinMontague CorbinMontague changed the title SwiftUI's native dismiss environment value does not work from modal cover with navigation SwiftUI's native dismiss environment value does not work from fullscreen modal with navigation Oct 7, 2024
@johnpatrickmorgan
Copy link
Owner

Thanks for raising this issue @CorbinMontague ! To update you, I can reproduce the bug, but I'm not yet sure why it's happening.

@CorbinMontague
Copy link
Author

@johnpatrickmorgan It looks like the issue is tied to the content being wrapped in a NavigationView vs a NavigationStack, because if I change UseNavigationStackPolicyKey's defaultValue to be UseNavigationStackPolicy.whenAvailable instead of UseNavigationStackPolicy.never, I notice that EmbedModifier wraps the content inside a NavigationStack instead of a NavigationView, and this issue does not reproduce. So for some reason Apple's native DismissAction seems to work with NavigationStack, but not NavigationView in this case.

In View+UseNavigationStack.swift I see a comment about how func useNavigationStack() is not ready to be exposed publicly yet due to issues. Could you elaborate on what those issues are since I'm wanting to use UseNavigationStackPolicy.whenAvailable to fix this DismissAction issue?

@CorbinMontague
Copy link
Author

hmm I'm seeing some kind of hang when using UseNavigationStackPolicy.whenAvailable and attempting to push additional views from within my modal so I assume I'm starting to hit some of those "issues" referred to in the comment I mentioned given I did not have that issue with UseNavigationStackPolicy.never.

@johnpatrickmorgan
Copy link
Owner

hmm I'm seeing some kind of hang when using UseNavigationStackPolicy.whenAvailable and attempting to push additional views from within my modal so I assume I'm starting to hit some of those "issues" referred to in the comment I mentioned given I did not have that issue with UseNavigationStackPolicy.never.

Hi @CorbinMontague , yes that is indeed the issue that was holding me back from making that API public. Navigation seems to trigger an infinite loop currently.

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