#swiftui #parent-child #navigationview #swiftui-navigationlink #swiftui-navigationview
#swiftui #родитель-потомок #navigationview #swiftui-navigationlink #swiftui-navigationview
Вопрос:
Я использую SwiftUI в проекте, для которого требуется модель со структурой сущностей «один ко многим ко многим». Я использую навигационное представление на родительском уровне с навигационными ссылками на родительском и дочернем уровнях.
Это хорошо работает в том смысле, что я могу:
- Выберите дочерний элемент на родительском уровне, чтобы перейти к дочернему элементу
- Выберите внука на дочернем уровне, чтобы перейти к внуку
У меня есть дополнительное требование — предоставить кнопки 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)
}
}