1

I'm trying to conditionally show a custom button on a view only if it being presented modally. This could be done in UIKit, but I'm trying to do this in SwiftUI.

I tried using the environment variable presentationMode to check if it's being presented, but the flag is true in both cases:

@Environment(\.presentationMode) private var presentationMode

if presentationMode.wrappedValue.isPresented { // true in both cases
   ...
}

Is there a way for a view to know if it's being presented or if it's pushed?

Extra Context:

I'm trying to create a custom modifier that will automatically add a dismiss button on views that are reused in both scenarios:

struct OverlayDismissButtonModifier: ViewModifier {
    @Environment(\.presentationMode) private var presentationMode

    func body(content: Content) -> some View {
        content
            .overlay(
                Group {
                    if presentationMode.wrappedValue.isPresented { // <-- True in both cases :(
                        Button(action: { presentationMode.wrappedValue.dismiss() }) {
                            Label(LocalizedStringKey("Close"), systemImage: "xmark")
                                .labelStyle(IconOnlyLabelStyle())
                                .foregroundColor(Color(.label))
                                .padding(8)
                                .background(
                                    Circle()
                                        .fill(Color(.systemBackground).opacity(0.8))
                                )
                        }
                        .padding([.top, .trailing])
                    }
                },
                alignment: .topTrailing
            )
    }
}

extension View {
    func overlayDismissButton() -> some View {
        modifier(OverlayDismissButtonModifier())
    }
}
TruMan1
  • 33,665
  • 59
  • 184
  • 335
  • 1
    Can you not pass another custom environment variable at the point where the very is added modally vs inside navigation view? – New Dev Apr 23 '21 at 21:11
  • I'm trying to create a custom modifier that figures this out that I can attach to views that are reused in both scenarios. It's for adding a custom dismiss button for when presented or let the system create the nav back button otherwise. – TruMan1 Apr 23 '21 at 21:57
  • I added the custom modifier code for more context. – TruMan1 Apr 23 '21 at 22:02
  • You should track this in view model instead. – Asperi Apr 24 '21 at 08:49
  • Do you have any news about this problem? I am also trying to solve same. – Emre Önder Jan 07 '22 at 08:33

1 Answers1

0

This worked for me.

var body: some View {
    if isPresentedModally {
        Text("Presented modally")
    } else {
        Text("Pushed onto navigation stack")
    }
}
extension View {
    var isPresentedModally: Bool {
        guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
        let window = windowScene.windows.first
        else {
            return false
        }
        return window.rootViewController?.presentedViewController != nil
    }
Diego Renau
  • 109
  • 3