SwiftUI消除多个模态表

时间:2019-10-09 05:16:29

标签: ios swift swiftui

我在根视图中使用.sheet(isPresented: self.$showModal)来呈现模态。在模式中,我使用NavigationView引导用户浏览各个页面(对于用户个人资料构建器)。

在我的导航堆栈的最后一页中,我使用@Environment(\.presentationMode) var presentationMode和一个调用self.presentationMode.wrappedValue.dismiss()的按钮来关闭模态。但是,这只会关闭导航堆栈中的最后一页,而我只停留在上一页。我要做的是关闭整个导航堆栈,然后回到根视图。

向下滑动以消除模态会产生所需的结果,但是我想以编程方式使用该按钮。

在SwiftUI中当前是否可行?或者在模式表中使用NavigationView会带来问题吗?

3 个答案:

答案 0 :(得分:5)

解决方案 1 - 自定义 EnvironmentKey

一种可能的解决方案是使用注入到每个环境中的自定义 EnvironmentKey

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

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

演示:

enter image description here

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
            }
        }
    }
}

解决方案 2 - 关闭 UIKit rootViewController

struct SheetNavigationDetailView: View {

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

答案 1 :(得分:1)

您可以将showModal作为绑定传递到以下屏幕中,而不是使用presentationValue将showModal设置为false。

答案 2 :(得分:0)

@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")
        }