SwiftUI NavigationView 在尝试孙子上一个下一个导航时出现父子孙子场景问题

Mik*_*per 5 parent-child navigationview swiftui swiftui-navigationlink swiftui-navigationview

我在一个需要具有“一对多对多”实体结构的模型的项目中使用 SwiftUI。我在父级使用导航视图,在父级和子级使用导航链接。

这很有效,因为我可以:

  1. 在父级别选择一个孩子以导航到该孩子
  2. 在子级选择孙子以导航到孙子

我有一个额外的要求 - 在孙级别提供下一个和上一个按钮。我使用为导航链接提供的标签/选择功能来做到这一点。我给每个孙子一个数字索引标签,然后在子级别调用传入的函数,通过从索引中添加或减去一个来更改选定的子视图。

问题是,当我导航到下一个或上一个孙子时,“返回”链接更改为最后访问的孙子,或者“返回”一词而不是子视图。如果我然后选择该视图上的“返回”链接,则会立即转换到以前访问过的孙子视图,然后立即转换到子视图。

包含的代码是一个工作项目,它显示了一个使用“一对一对多”场景的更简单的示例,该场景具有相同的问题。

如果我将代码更改为更简单的父子模型,并且在子级别使用 next 和 previous 这一切都按预期工作,所以问题是由三个级别造成的。非常欢迎任何有关解决方案的帮助。

//
//  ContentView.swift
//  NextPreviousTest
//
//  Created by Mike Cooper on 26/09/2020.
//
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        NavigationView {
            VStack {
                Spacer()
                NavigationLink(destination: ChildView()) {
                    Text("Child View")
                }.buttonStyle(PlainButtonStyle())
                Spacer()
            }.navigationBarTitle(Text("Parent"), displayMode: .inline)
        }
    }
        
}

struct ChildView: View {
    @State private var array = [0, 1, 2, 3, 4, 5]
    @State private var selectedGrandChild: String? = nil
    
    var body: some View {
        ScrollView {
            ForEach(0..<array.count) { i in
                NavigationLink(destination: GrandChildView(viewIndex: self.array[i], prevFunction: childView_prevFunction,
                                                      nextFunction: childView_nextFunction
                )
                , tag: String(self.array[i]), selection: $selectedGrandChild) {
                    Text("Grandchild \(self.array[i])").padding()
                }.buttonStyle(PlainButtonStyle())
            }
        }.navigationBarTitle(Text("Child"), displayMode: .inline)
    }
    
    private func childView_prevFunction() {
        let tag = Int(self.selectedGrandChild ?? "0")
        if tag! > 0 {
            self.selectedGrandChild = String(tag! - 1)
            print(String(tag! - 1))
        }
    }
    
    private func childView_nextFunction() {
        let tag = Int(self.selectedGrandChild ?? "0")
        if tag! < self.array.count - 1 {
            self.selectedGrandChild = String(tag! + 1)
            print(String(tag! + 1))
        }
    }
    
}

struct GrandChildView: View {
    
    let viewIndex: Int
    var prevFunction: () -> Void
    var nextFunction: () -> Void
    
    var body: some View {
        VStack{
            HStack {
                Button(action: {
                    self.prevFunction()
                }) {
                    Image(systemName: "chevron.left")
                }
                Text("Grandchild \(viewIndex)")
                Button(action: {
                    self.nextFunction()
                }) {
                    Image(systemName: "chevron.right")
                }
            }.font(.headline)
        }.navigationBarTitle("Grandchild \(viewIndex)").font(.caption)
    }
}
Run Code Online (Sandbox Code Playgroud)