I have a SwiftUI app with a tab view within a navigation view. Changing the iPhone orientation (portrait to landscape or landscape back to portrait) while in a menu child view results with system control returning to the tab view menu rather than just redrawing the view. Re-orientating any of the tab views works as expected with a redraw of the view.
The sample code below is a complete example with a menu on tab E. Selecting for example "Edit option C" from the menu will take you to a view that states "This is option C". Changing the orientation of the iPhone results in return to the tab E menu view with the menu squashed in the left half of the screen rather than displaying "This is option C" in the new orientation.
Am I missing something or is this "normal" Swift behavior?
enum Tabs: String {
case home
case tabb
case tabc
case tabd
case tabe
}
struct ContentView: View {
@State private var selectedTab: Tabs = .home
var body: some View {
NavigationView {
TabView (selection: $selectedTab) {
TabAView()
.tabItem {
Label("Tab A", systemImage: "house.circle.fill")
}.tag(Tabs.home)
TabBView()
.tabItem {
Label("Tab B", systemImage: "b.circle.fill")
}.tag(Tabs.tabb)
TabCView()
.tabItem {
Label("Tab C", systemImage: "c.circle.fill")
}.tag(Tabs.tabc)
TabDView()
.tabItem {
Label("Tab D", systemImage: "d.circle.fill")
}.tag(Tabs.tabd)
TabEView()
.tabItem {
Label("Tab E", systemImage: "e.circle.fill")
}.tag(Tabs.tabe)
}
}.accentColor(.green)
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct TabAView: View {
var body: some View {
Text("This is tab A")
}
}
struct TabBView: View {
var body: some View {
Text("This is tab B")
}
}
struct TabCView: View {
var body: some View {
Text("This is tab C")
}
}
struct TabDView: View {
var body: some View {
Text("This is tab D")
}
}
struct TabEView: View {
var body: some View {
GeometryReader { g in
VStack (alignment: .leading) {
Text("Tab E")
.font(.title2)
.fontWeight(.bold)
.padding(.leading, 20)
List {
NavigationLink(destination: AView()) {Text("Edit Option A")}
NavigationLink(destination: BView()) {Text("Edit Option B")}
NavigationLink(destination: CView()) {Text("Edit Option C")}
NavigationLink(destination: DView()) {Text("Edit Option D")}
}
.font(.body)
.environment(\.defaultMinListRowHeight, 12)
.padding(.leading, 25)
}
}
}
}
struct AView: View {
var body: some View {
Text("This is option A")
}
}
struct BView: View {
var body: some View {
Text("This is option B")
}
}
struct CView: View {
var body: some View {
Text("This is option C")
}
}
struct DView: View {
var body: some View {
Text("This is option D")
}
}
This is the order. The NavigationView encapsulates each Primary view of the tab view item. The TabView encapsulates all of the NavigationViews
TabView {
NavigationView {
TabAView()
}
.tabItem {
Label {
Label("Tab A", systemImage: "house.circle.fill")
} icon: {
Image(systemName: "clock")
}
}
.tag(Tabs.taba)
NavigationView {
TabBView()
}
.tabItem {
Label {
Label("Tab B", systemImage: "house.circle.fill")
} icon: {
Image(systemName: "clock")
}
}
.tag(Tabs.tabb)
}