NavigationView 在 swiftUI 中的使用

NavigationView usage in swiftUI

来自 Android 并且正在处理一个非常复杂的应用程序,我想尽可能多地使用 NavigationView。拥有一个视图并使所有元素在此视图上出现和消失对我来说似乎无法处理。 我正在使用 navigationView 在隐藏了 navigationBar 的视图之间导航。 这种导航或显示视图的方式对用户来说是透明的

经过一些测试,我遇到了限制:在导航的第 13 级或第 14 级,一切都消失了,应用程序基本上崩溃了。

再次强调,这是 2 个内容视图之间的直接导航,没有主屏幕

import SwiftUI

struct test4: View {
    
    @State private var intent3: Bool =  false

    var body: some View {
      
        NavigationView{
  
            VStack{
                NavigationLink(destination : test3() , isActive : $intent3) { }
                Text("ver 4")
            .onTapGesture {
            intent3 = true }
                Spacer()
            }
            
        }
        .navigationBarHidden(true)
    }
    
}

import SwiftUI


struct test3: View {
    
    @State private var intent4: Bool =  false

    var body: some View {
      
        NavigationView{
  
            VStack{
                NavigationLink(destination : test4() , isActive : $intent4) { }
                Text("ver 3")
            .onTapGesture {
            intent4 = true }
                Spacer()
            }
        }.navigationBarHidden(true)    }
}

这里是直接在 2 个内容视图之间导航的基本示例。点击 14/15 次后崩溃。我在任何导航 link.

上都遇到了同样的问题

更新: 使用您添加的代码,我可以看到最初的崩溃是每次添加新的 NavigationView 的结果。这解决了它:


struct ContentView: View {
    var body: some View {
        NavigationView {
            Test3()
        }
    }
}

struct Test4: View {
    @State private var intent3: Bool =  false
    var body: some View {
        VStack{
            NavigationLink(destination : Test3() , isActive : $intent3) { }
            Text("ver 4")
                .onTapGesture {
                    intent3 = true
                }
            Spacer()
        }
        .navigationBarHidden(true)
    }
}

struct Test3: View {
    @State private var intent4: Bool =  false
    var body: some View {
        VStack{
            NavigationLink(destination : Test4() , isActive : $intent4) { }
            Text("ver 3")
                .onTapGesture {
                    intent4 = true }
            Spacer()
        }
        .navigationBarHidden(true)
    }
}

原回答:

但是,有一些解决方案可以弹出到导航层次结构的顶部。

一种方法是使用 isActive 来管理给定的 NavigationLink 是否呈现其视图。这可能看起来像这样:

class NavigationReset : ObservableObject {
    @Published var rootIsActive = false
    
    func popToTop() {
        rootIsActive = false
    }
}

struct ContentView: View {
    @StateObject private var navReset = NavigationReset()
    
    var body: some View {
        NavigationView {
            NavigationLink(destination: DetailView(title: "First"), isActive: $navReset.rootIsActive) {
                Text("Root nav")
            }
        }.environmentObject(navReset)
    }
}

struct DetailView : View {
    var title : String
    @EnvironmentObject private var navReset : NavigationReset
    
    var body: some View {
        VStack {
            NavigationLink(destination: DetailView(title: "\(Date())")) {
                Text("Navigate (\(title))")
            }
            Button("Reset nav") {
                navReset.popToTop()
            }
        }
    }
}

您可以使用的另一个技巧是更改 NavigationLink 上的 id - 一旦发生这种情况,它就会重新呈现并变为非活动状态。

class NavigationReset : ObservableObject {
    @Published var id = UUID()
    
    func popToTop() {
        id = UUID()
    }
}

struct ContentView: View {
    @StateObject private var navReset = NavigationReset()
    
    var body: some View {
        NavigationView {
            NavigationLink(destination: DetailView(title: "First")) {
                Text("Root nav")
            }
            .id(navReset.id)
        }.environmentObject(navReset)
    }
}

struct DetailView : View {
    var title : String
    @EnvironmentObject private var navReset : NavigationReset
    
    var body: some View {
        VStack {
            NavigationLink(destination: DetailView(title: "\(Date())")) {
                Text("Navigate (\(title))")
            }
            Button("Reset nav") {
                navReset.popToTop()
            }
        }
    }
}

它的工作原理是用 id 标记第一个 NavigationLink(即主屏幕上的那个)。一旦 id 被更改,NavigationLink 就会被重新创建,从堆栈中弹出所有视图。