SwiftUI 2.0:关闭按钮没有关闭视图 - 如何让关闭按钮返回上一个视图?

时间:2021-01-01 23:24:27

标签: swiftui ios14

在此频道和网络上进行研究时,我尝试使用各种示例中的按钮和导航链接。 NavigationLink 没问题,只是 NavigationView 在我的视图中将所有内容向下推。

我有一个包含图像和文本的视图,如下所示:( x 关闭) 但是当我使用下面的代码时,关闭按钮没有做任何事情。

ContentView() 中,我有一个 (?) 按钮,可将我从 WalkthroughView() 转到 PageTabView,然后转到此视图 TabDetailsView:

ContentView():

ZStack {
        NavigationView {
            VStack {
                Text("Hello World")
                    .padding()
                    .font(.title)
                    .background(Color.red)
                    .foregroundColor(.white)
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button {
                        withAnimation {
                            showOnBoarding = true
                        }
                    } label: {
                        Image(systemName: "questionmark.circle.fill")
                    }
                }
            }
        }
        .accentColor(.red)
        .disabled(showOnBoarding)
        .blur(radius: showOnBoarding ? 3.0 : 0)
        
        if showOnBoarding {
            WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing)
        }
    }
    .onAppear {
        if !isWalkthroughViewShowing {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                withAnimation {
                    showOnBoarding.toggle()
                    isWalkthroughViewShowing = true
                }
            }
        }
    }

WalkthroughView():

var body: some View {
    ZStack {
        GradientView()
        VStack {
            PageTabView(selection: $selection)

            // shows Previous/Next buttons only
            ButtonsView(selection: $selection) 
        }
    }
    .transition(.move(edge: .bottom))
}

PageTabView():

var body: some View {
    TabView(selection: $selection) {
        ForEach(tabs.indices, id: \.self) { index in
            TabDetailsView(index: index)
        }
    }
    .tabViewStyle(PageTabViewStyle())
}

下面是 TabDetailsView():

在视图的顶部是这个关闭按钮,当按下时,应该让我回到 ContentView,但什么也没有发生。

struct TabDetailsView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    let index: Int

然后,在身体内部:

VStack(alignment: .leading) {
        Spacer()
        VStack(alignment: .leading) {
            // Button to close each walkthrough page...
            Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }) {
                Image(systemName: "xmark.circle.fill")
                Text("Close")
            }
            .padding(.leading)
            .font(.title2)
            .accentColor(.orange)

            Spacer()
            VStack {
                Spacer()
                Image(tabs[index].image)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 415)
                    .padding(.leading, 10)
                
                Text(tabs[index].title)
                    .font(.title)
                    .bold()
                
                Text(tabs[index].text)
                    .padding()
                Spacer()
            }
            .foregroundColor(.white)
        }
    }

1 个答案:

答案 0 :(得分:1)

<块引用>
    if showOnBoarding {
        WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing)
    }

像上面那样插入视图不是标准意义上的演示,这就是提供的代码不起作用的原因。

由于此视图通过 showOnBoarding 显示,因此也应通过 showOnBoarding 隐藏,因此解决方案是将对此状态的绑定传递到视图中,然后将其切换回。

由于层次结构较深,最合适的方法是使用自定义环境值。为简单起见,让我们使用 https://stackoverflow.com/a/61847419/12299030 中的 ResetDefault(您可以在代码中重命名)

所以需要修改:

    if showOnBoarding {
        WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing)
          .environment(\.resetDefault, $showOnBoarding)
    }

在子视图中

struct TabDetailsView: View {
    @Environment(\.resetDefault) var showOnBoarding

    // .. other code

            Button(action: {
                self.showOnBoarding.wrappedValue.toggle() 
            }) {
                Image(systemName: "xmark.circle.fill")
                Text("Close")
            }