Условные ссылки навигации в родительском представлении Принудительный переход из дочернего представления обратно в родительский вид, когда условие больше не выполняется
import SwiftUI
struct ConditionalNavigationParentView: View {
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
var body: some View {
NavigationView {
// iPhone Portrait
if horizontalSizeClass == .compact && verticalSizeClass == .regular {
VStack {
Text("This is the Parent View.")
.foregroundColor(Color.black)
.font(.headline)
NavigationLink(destination: ConditionalNavigationChildView()) {
Text("Navigate to Child View.")
.font(.body)
}
}
}
// iPhone Landscape
if verticalSizeClass == .compact {
HStack {
Text("This is the Parent View.")
.foregroundColor(Color.black)
.font(.headline)
NavigationLink(destination: ConditionalNavigationChildView()) {
Text("Navigate to Child View.")
.font(.body)
}
}
}
}
}
}
struct ConditionalNavigationChildView: View {
var body: some View {
Text("This is the Child View.")
.font(.headline)
}
}
В приведенном выше коде у нас есть родительский вид и дочерний вид. Родительское представление содержит условный заголовок и ссылку для навигации. Дочернее представление содержит заголовок. Когда вы переходите к дочернему представлению, навигация работает нормально. Однако, как только условие, содержащее навигационную ссылку в родительском представлении, больше не выполняется (путем поворота устройства с книжной на альбомную), соединение, сохраняющее дочерний и родительский виды для навигации, прерывается и заставляет вернуться к родительскому представлению. Похоже, это связано с тем, что SwiftUI, как сейчас, необходимо перерисовать компоненты из родительского представления. В приведенном выше примере одним из решений было бы сделать только текст условным и удерживать навигационную ссылку одновременно в vstack и hstack, например:
import SwiftUI
struct ConditionalNavigationParentView: View {
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
var body: some View {
NavigationView {
VStack {
// iPhone Portrait
if horizontalSizeClass == .compact && verticalSizeClass == .regular {
Text("This is the Parent View.")
.foregroundColor(Color.black)
.font(.headline)
}
HStack {
// iPhone Landscape
if verticalSizeClass == .compact {
Text("This is the Parent View.")
.foregroundColor(Color.black)
.font(.headline)
}
NavigationLink(destination: ConditionalNavigationChildView()) {
Text("Navigate to Child View.")
.font(.body)
}
}
}
}
}
}
struct ConditionalNavigationChildView: View {
var body: some View {
Text("This is the Child View.")
.font(.headline)
}
}
Хотя в данном случае это действительно решает проблему с навигацией, другие случаи с несколькими навигационными ссылками кажутся совершенно невозможными. Например, вы заменяете заголовок другой навигационной ссылкой. Второй по-прежнему будет работать нормально, так как он не является условным, но первый и все его подвиды будут возвращены в родительский вид при повороте.
В UIKit это никогда не было бы проблемой, поскольку условная навигация не возвращает в родительское представление, как это. Так это ошибка SwiftUI? Или это намеренное поведение? Если это предполагаемое поведение, какое решение существует для представления с несколькими условными ссылками навигации?