使用 "static nav bar" 关闭视图

Dismissing a View using a "static nav bar"

我创建了一个用作导航栏的简单视图,其中包含一个菜单按钮和一些文本。我将其用作我的 NavigationView 之外的 top-level 元素,这使我可以在进入视图的所有 child 页面上拥有静态视图。我尝试不使用带有导航栏项目的默认导航栏的原因是为了避免在切换视图时伴随淡入淡出的动画 dismissal/creation。

我现在面临的问题是当我离开 parent 视图时关闭 child 视图。我能够将按钮从菜单图标更新为后退图标,但未触发按钮的操作。一直在网上查看是否有人做过类似的事情但没有运气,我不确定我想要实现的目标是否有可能或者我是否正在以正确的方式进行。即使在根视图中初始化了 header,是否仍然可以从 child 视图调用 self.presentationMode.wrappedValue.dismiss()?感谢任何帮助,这是我目前所拥有的:

根视图(View1):

struct View1: View {
    @State var showMenuButton: Bool = false
    var body: some View {
        VStack {
            CustomNavigationView(showMenuButton: self.showMenuButton)

            NavigationView {
                NavigationLink(destination: View2()) {
                    Text("View 2")
                }
                .navigationBarTitle("")
                .navigationBarHidden(true)
                .onDisappear(){
                    self.showMenuButton = false
                }
                .onAppear() {
                    self.showMenuButton = true
                }
            }
        }
    }
}

Child 根视图(View2)的视图:

struct View2: View {
    var body: some View {
        VStack{
            Text("This is View 2")
            .navigationBarTitle("")
            .navigationBarHidden(true)
            NavigationLink(destination: View3()) {
                Text("View 3")
            }
        }
    }
}

Child 视图 2 (View3) 的视图:

struct View3: View {
    var body: some View {
        VStack{
            Text("This is View 3")
            .navigationBarTitle("")
            .navigationBarHidden(true)
        }
    }
}

自定义导航视图:

struct CustomNavigationView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var showMenuButton = false
    var body: some View {
        VStack {
            HStack {
                if showMenuButton {
                    Button(action: {
                        //Do Something
                    }) {
                        Image(systemName: "line.horizontal.3")
                        .foregroundColor(.black)
                    }
                } else {
                    Button(action: { self.presentationMode.wrappedValue.dismiss()}) {
                        Image(systemName: "arrow.left")
                        .foregroundColor(.black)
                    }
                }
                Text("Sometext")            
            }
        }
    }
}

您在第一个视图中使用的环境对象 'presentationMode' 无法关闭您推送的视图。每一个想要被驳回的观点都必须有自己的对象。第一个视图中的对象不属于任何其他推送的视图。因此,您需要创建视图模型来管理此任务。

这是示例代码。希望能帮助您解决问题。

class NavigationObserver: ObservableObject {
    private var views: [Int:Binding<PresentationMode>] = [:]
    private var current: Int = 0

    func popView() {
       guard let view = views[current] else {
          return
       }
       view.wrappedValue.dismiss()
       views[current] = nil
       current -= 1
     }

    func pushView(id: Int, newView: Binding<PresentationMode>) {
       guard views[id] == nil else {
          return
       }
       current += 1
       views[id] = newView
     }
   }

struct ContentView: View {
@State var showMenuButton: Bool = false
@ObservedObject var observer = NavigationObserver()
var body: some View {
    VStack {
        CustomNavigationView(observer: self.observer, showMenuButton: self.showMenuButton)

        NavigationView {
            NavigationLink(destination: View2(observer: self.observer)) {
                Text("View 2")
            }
            .navigationBarTitle("")
            .navigationBarHidden(true)
            .onDisappear(){
                self.showMenuButton = false
            }
            .onAppear() {
                self.showMenuButton = true
            }
        }
    }
}}
struct View2: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var observer: NavigationObserver
var body: some View {
    VStack{
        Text("This is View 2")
        .navigationBarTitle("")
        .navigationBarHidden(true)
        NavigationLink(destination: View3(observer: self.observer)) {
            Text("View 3")
        }
    }.onAppear {
        self.observer.pushView(id: 1, newView: self.presentationMode)
    }
}}

struct View3: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var observer: NavigationObserver
var body: some View {
    VStack{
        Text("This is View 3")
        .navigationBarTitle("")
        .navigationBarHidden(true)
    }.onAppear
        {
            self.observer.pushView(id: 2, newView: self.presentationMode)
        }
}
}

struct CustomNavigationView: View {
@ObservedObject var observer: NavigationObserver
var showMenuButton = false
var body: some View {
    VStack {
        HStack {
            if showMenuButton {
                Button(action: {
                    //Do Something
                }) {
                    Image(systemName: "line.horizontal.3")
                    .foregroundColor(.black)
                }
            } else {
                Button(action: {
                    self.observer.popView()
                }) {
                    Image(systemName: "arrow.left")
                    .foregroundColor(.black)
                }
            }
            Text("Sometext")
        }
    }
}
}

谢谢,X_X