如何从导航树return到起始视图?
How to return to the starting view from the navigation tree?
假设我有一个数组,我首先在另一个视图中追加一个元素,然后在第三个视图中追加第二个元素。如何return到起始视图并从内存中推断出两个额外的视图?
struct ContentView: View {
@State var array: [String] = []
var body: some View {
NavigationView{
ScrollView{
ForEach(array, id: \.self) { element in
Text(element)
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink("+") {
Details(array: $array)
}
}
}
}
}
}
struct Details: View {
@Binding var array: [String]
var body: some View {
Button(action: { array.append("First Element") }) {
Text("Append First Element")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink("+") {
}
}
}
}
}
struct MoreDetails: View {
@Binding var array: [String]
@Environment(\.dismiss) var dismiss
var body: some View {
Button(action: { array.append("Second Element") }) {
Text("Append Second Element")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink("Done") {
ContentView(array: array)
}
.simultaneousGesture(TapGesture().onEnded{
dismiss()
})
}
}
}
}
您真正遇到的问题是导航问题,或者至少是您认为自己想要导航的方式。你设置的导航是这样的:
Original ContentView -> Details -> MoreDetails -> New ContentView
当你想要的是:
Original ContentView -> Details -> MoreDetails -> Original ContentView
无需返回浏览所有视图。要做到这一点,基本上就是搭建一个纸牌屋,然后将底部的卡片拉出,然后您的导航会折叠回原来的状态 ContentView
。注释代码:
struct ContentView: View {
@State var array: [String] = []
// originalIsActive is your bottom card, and you will carry a reference
// through your views like a piece of twine.
@State var originalIsActive = false
var body: some View {
NavigationView{
ScrollView{
ForEach(array, id: \.self) { element in
Text(element)
}
}
.background(
// This is a programatic NavigationLink that triggers when originalIsActive
// becomes true. Placed in a background it sits and listens for originalIsActive.
NavigationLink(isActive: $originalIsActive, destination: {
Details(array: $array, originalIsActive: $originalIsActive)
}, label: {
// This is simply a nothing view, so you can't see the NavigationLink.
EmptyView()
})
// Necessary to prevent link pop back after this NavigationLink
.isDetailLink(false)
)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
// This Button sets originalIsActive to true, activating the NavigationLink.
originalIsActive = true
} label: {
Image(systemName: "plus")
}
}
}
}
}
}
struct Details: View {
@Binding var array: [String]
// Reference to originalIsActive
@Binding var originalIsActive: Bool
@State var detailsIsActive = false
var body: some View {
Button(action: { array.append("First Element") }) {
Text("Append First Element")
}
.background(
NavigationLink(isActive: $detailsIsActive, destination: {
MoreDetails(array: $array, originalIsActive: $originalIsActive)
}, label: {
EmptyView()
})
// Necessary to prevent link pop back after this NavigationLink
.isDetailLink(false)
)
.toolbar {
Button {
detailsIsActive = true
} label: {
Image(systemName: "plus")
}
}
}
}
struct MoreDetails: View {
@Binding var array: [String]
// Reference to originalIsActive
@Binding var originalIsActive: Bool
var body: some View {
Button(action: { array.append("Second Element") }) {
Text("Append Second Element")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
// By setting originalIsActive to false, you pull out the bottom card.
// If the first link does not exist, none do.
originalIsActive = false
} label: {
Text("Original")
}
}
}
}
}
假设我有一个数组,我首先在另一个视图中追加一个元素,然后在第三个视图中追加第二个元素。如何return到起始视图并从内存中推断出两个额外的视图?
struct ContentView: View {
@State var array: [String] = []
var body: some View {
NavigationView{
ScrollView{
ForEach(array, id: \.self) { element in
Text(element)
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink("+") {
Details(array: $array)
}
}
}
}
}
}
struct Details: View {
@Binding var array: [String]
var body: some View {
Button(action: { array.append("First Element") }) {
Text("Append First Element")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink("+") {
}
}
}
}
}
struct MoreDetails: View {
@Binding var array: [String]
@Environment(\.dismiss) var dismiss
var body: some View {
Button(action: { array.append("Second Element") }) {
Text("Append Second Element")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink("Done") {
ContentView(array: array)
}
.simultaneousGesture(TapGesture().onEnded{
dismiss()
})
}
}
}
}
您真正遇到的问题是导航问题,或者至少是您认为自己想要导航的方式。你设置的导航是这样的:
Original ContentView -> Details -> MoreDetails -> New ContentView
当你想要的是:
Original ContentView -> Details -> MoreDetails -> Original ContentView
无需返回浏览所有视图。要做到这一点,基本上就是搭建一个纸牌屋,然后将底部的卡片拉出,然后您的导航会折叠回原来的状态 ContentView
。注释代码:
struct ContentView: View {
@State var array: [String] = []
// originalIsActive is your bottom card, and you will carry a reference
// through your views like a piece of twine.
@State var originalIsActive = false
var body: some View {
NavigationView{
ScrollView{
ForEach(array, id: \.self) { element in
Text(element)
}
}
.background(
// This is a programatic NavigationLink that triggers when originalIsActive
// becomes true. Placed in a background it sits and listens for originalIsActive.
NavigationLink(isActive: $originalIsActive, destination: {
Details(array: $array, originalIsActive: $originalIsActive)
}, label: {
// This is simply a nothing view, so you can't see the NavigationLink.
EmptyView()
})
// Necessary to prevent link pop back after this NavigationLink
.isDetailLink(false)
)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
// This Button sets originalIsActive to true, activating the NavigationLink.
originalIsActive = true
} label: {
Image(systemName: "plus")
}
}
}
}
}
}
struct Details: View {
@Binding var array: [String]
// Reference to originalIsActive
@Binding var originalIsActive: Bool
@State var detailsIsActive = false
var body: some View {
Button(action: { array.append("First Element") }) {
Text("Append First Element")
}
.background(
NavigationLink(isActive: $detailsIsActive, destination: {
MoreDetails(array: $array, originalIsActive: $originalIsActive)
}, label: {
EmptyView()
})
// Necessary to prevent link pop back after this NavigationLink
.isDetailLink(false)
)
.toolbar {
Button {
detailsIsActive = true
} label: {
Image(systemName: "plus")
}
}
}
}
struct MoreDetails: View {
@Binding var array: [String]
// Reference to originalIsActive
@Binding var originalIsActive: Bool
var body: some View {
Button(action: { array.append("Second Element") }) {
Text("Append Second Element")
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
// By setting originalIsActive to false, you pull out the bottom card.
// If the first link does not exist, none do.
originalIsActive = false
} label: {
Text("Original")
}
}
}
}
}