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? Или это намеренное поведение? Если это предполагаемое поведение, какое решение существует для представления с несколькими условными ссылками навигации?