swiftUI中的NavigationView用法
我来自Android,正在开发一个非常复杂的应用程序,我希望尽可能多地使用NavigationView。对于我来说,拥有一个视图并使所有元素在该视图上出现和消失似乎是不可能的。 我使用navigationView在导航栏隐藏的视图之间导航。 这种导航或显示视图的方式对用户来说是透明的 经过一些测试,我遇到了一些限制:在第13或14级导航时,所有内容都消失了,应用程序基本上崩溃了 同样,这是两个内容视图之间的直接导航,没有主屏幕swiftUI中的NavigationView用法,swiftui,swiftui-navigationlink,Swiftui,Swiftui Navigationlink,我来自Android,正在开发一个非常复杂的应用程序,我希望尽可能多地使用NavigationView。对于我来说,拥有一个视图并使所有元素在该视图上出现和消失似乎是不可能的。 我使用navigationView在导航栏隐藏的视图之间导航。 这种导航或显示视图的方式对用户来说是透明的 经过一些测试,我遇到了一些限制:在第13或14级导航时,所有内容都消失了,应用程序基本上崩溃了 同样,这是两个内容视图之间的直接导航,没有主屏幕 import SwiftUI struct test4: View
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)
}
}
这里是直接在两个内容视图之间导航的基本示例。点击14/15次后崩溃。关于任何导航链接,我都会遇到同样的问题。更新:
通过您添加的代码,我可以看出最初的崩溃是由于每次添加新的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()
}
}
}
}
您可以使用的另一个技巧是更改导航链接上的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
。一旦更改了id
,就会重新创建NavigationLink
,弹出堆栈中的所有视图。首先,非常感谢您花费的时间。我很难理解这一切。关于“自身崩溃”:NavigationView{您的评论结尾可能缺少某些内容。如果您需要对我的答案中的某些内容进行更多说明,请告诉我。如果没有额外的代码,其中的许多内容将无法编译。与其将其作为评论添加,不如尝试添加所有相关代码作为问题的编辑。但是,可能只有在我的解决方案由于某些原因,它对您不起作用。很抱歉,这是代码,单击13/14次应该会产生崩溃。我认为这是正常行为,因为它在其他导航视图中正好附加了14次单击。如果导航栏未隐藏,则使其崩溃是有意义的。如果导航不应受到限制(无母视图),为什么需要实现一些额外的代码呢?Thanx再次提醒您,您编辑的示例会崩溃,因为您每次都嵌入了一个新的NavigationView
。将其仅放在父元素上,效果很好。感谢jpnpdx帮助我解决此问题。对于像我这样的非swift专家,我想补充一点,sol导航中不提供“平等”。与android不同,总是会有一个“根视图”(即使用户看不到它)。根视图的路径将保持不变,即使未关闭。jnpdx带来的其他元素允许一条“直线”到根视图
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()
}
}
}
}