简体   繁体   English

SwiftUI 关闭多个模态表

[英]SwiftUI Dismiss Multiple Modal Sheets

I am using .sheet(isPresented: self.$showModal) in my root view to present a modal.我在根视图中使用.sheet(isPresented: self.$showModal)来呈现模式。 Within the modal, I am using NavigationView to take the user through various pages (for a user profile builder).在模式中,我使用NavigationView引导用户浏览各个页面(对于用户配置文件构建器)。

In the last page of my navigation stack, I am using @Environment(\.presentationMode) var presentationMode and a button which calls self.presentationMode.wrappedValue.dismiss() to dismiss the modal.在我的导航堆栈的最后一页中,我正在使用@Environment(\.presentationMode) var presentationMode和一个调用self.presentationMode.wrappedValue.dismiss()的按钮来关闭模式。 However, this only dismisses the last page in the navigation stack, and I just end up at the previous page.但是,这只会关闭导航堆栈中的最后一页,而我只是在前一页结束。 What I want to do is dismiss the entire navigation stack and end up back at the root view.我想要做的是关闭整个导航堆栈并最终回到根视图。

Swiping down to dismiss the modal produces the desired result, but I want to do this programatically with the button.向下滑动以关闭模式会产生所需的结果,但我想使用按钮以编程方式执行此操作。

Is this currently possible in SwiftUI, or is this a problem with using NavigationView within a modal sheet?这目前在 SwiftUI 中是否可行,或者这是在模态表中使用NavigationView的问题?

Solution 1 - Custom EnvironmentKey解决方案 1 - 自定义 EnvironmentKey

A possible solution is to use a custom EnvironmentKey injected to every environment:一种可能的解决方案是使用注入到每个环境的自定义EnvironmentKey

struct PresentationKey: EnvironmentKey {
    static let defaultValue: [Binding<Bool>] = []
}

extension EnvironmentValues {
    var presentations: [Binding<Bool>] {
        get { return self[PresentationKey] }
        set { self[PresentationKey] = newValue }
    }
}

Demo:演示:

在此处输入图像描述

struct ContentView: View {
    @Environment(\.presentations) private var presentations
    @State private var showSheet = false

    var body: some View {
        Button("Show sheet") {
            showSheet = true
        }
        .sheet(isPresented: $showSheet) {
            SheetView()
                .environment(\.presentations, presentations + [$showSheet])
        }
    }
}
struct SheetView: View {
    @Environment(\.presentations) private var presentations
    @State private var showSheet = false

    var body: some View {
        Button("Show another sheet") {
            showSheet = true
        }
        .sheet(isPresented: $showSheet) {
            SheetNavigationView()
                .environment(\.presentations, presentations + [$showSheet])
        }
    }
}
struct SheetNavigationView: View {
    var body: some View {
        NavigationView {
            NavigationLink("Link", destination: SheetNavigationDetailView())
        }
    }
}
struct SheetNavigationDetailView: View {
    @Environment(\.presentations) private var presentations

    var body: some View {
        Button("Pop to root") {
            presentations.forEach {
                $0.wrappedValue = false
            }
        }
    }
}

Solution 2 - Dismiss UIKit rootViewController解决方案 2 - 关闭 UIKit rootViewController

struct SheetNavigationDetailView: View {

    var body: some View {
        Button("Pop to root") {
            UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true)
        }
    }
}

You can pass showModal as a binding into the following screens and instead of using presentationValue set showModal to false.您可以将 showModal 作为绑定传递到以下屏幕,而不是使用 presentationValue 将 showModal 设置为 false。

@State private var modalOpen: Bool = false

.sheet(isPresented: self.$modalOpen, onDismiss: {
            // code that triggers when modal is closed
        }) {
        Button(action: {
            self.modalOpen.toggle()
        }) {
           Text("Schließen")
        }

In SwiftUI.在 SwiftUI 中。

Use SheetKit to dismiss all sheets with animation controll.使用SheetKit通过 animation 控件关闭所有工作表。

SheetKit().dismissAllSheets(animation:false)

or Use NavigationViewKit to pop back to root view in navigationView或使用NavigationViewKit在 navigationView 中弹回根视图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM