SwiftUI bug, when removing a TabView all other tabs have `onAppear` and `onDisappear` triggered

  • Xcode 14.1
  • Running on iPhone 14 Pro max simulator 16.1

Code...

import SwiftUI

struct ContentView: View {
	@State var loggedIn: Bool = false

	var body: some View {
		switch loggedIn {
		case false:
			Button("Login") {
				loggedIn = true
			}
			.onAppear {
				print("🍏 Login on appear")
			}
			.onDisappear {
				print("🍎 Login on disappear")
			}
		case true:
			TabView {
				NavigationView {
					Text("Home")
						.navigationBarTitle("Home")
						.onAppear {
							print("🍏 Home on appear")
						}
						.onDisappear {
							print("🍎 Home on disappear")
						}
						.toolbar {
							ToolbarItem(placement: .navigationBarTrailing) {
								Button("Logout") {
									loggedIn = false
								}
							}
						}
				}
				.tabItem {
					Image(systemName: "house")
					Text("Home")
				}

				NavigationView {
					Text("Savings")
						.navigationBarTitle("Savings")
						.onAppear {
							print("🍏 Savings on appear")
						}
						.onDisappear {
							print("🍎 Savings on disappear")
						}
						.toolbar {
							ToolbarItem(placement: .navigationBarTrailing) {
								Button("Logout") {
									loggedIn = false
								}
							}
						}
				}
				.tabItem {
					Image(systemName: "dollarsign.circle")
					Text("Savings")
				}

				NavigationView {
					Text("Profile")
						.navigationBarTitle("Profile")
						.onAppear {
							print("🍏 Profile on appear")
						}
						.onDisappear {
							print("🍎 Profile on disappear")
						}
						.toolbar {
							ToolbarItem(placement: .navigationBarTrailing) {
								Button("Logout") {
									loggedIn = false
								}
							}
						}
				}
				.tabItem {
					Image(systemName: "person")
					Text("Profile")
				}
			}
			.onAppear {
				print("🍏 Tabview on appear")
			}
			.onDisappear {
				print("🍎 Tabview on disappear")
			}
		}
	}
}

Video of bug... https://youtu.be/oLKjRGL2lX0

Example steps...

  1. Launch app
  2. Tap Login
  3. Tap Savings tab
  4. Tap Home tab
  5. Tap Logout

Expected Logs...

  1. 🍏 Login on appear
  2. 🍏 Tabview on appear
  3. 🍏 Home on appear
  4. 🍎 Login on disappear
  5. 🍏 Savings on appear
  6. 🍎 Home on disappear
  7. 🍏 Home on appear
  8. 🍎 Savings on disappear
  9. 🍏 Login on appear
  10. 🍎 Home on disappear
  11. 🍎 Tabview on disappear

Actual logs...

  1. 🍏 Login on appear
  2. 🍏 Tabview on appear
  3. 🍏 Home on appear
  4. 🍎 Login on disappear
  5. 🍏 Savings on appear
  6. 🍎 Home on disappear
  7. 🍏 Home on appear
  8. 🍎 Savings on disappear
  9. 🍏 Login on appear
  10. 🍏 Savings on appear
  11. 🍎 Home on disappear
  12. 🍎 Savings on disappear
  13. 🍎 Tabview on disappear

Error...

10 and 12 in the actual logs should not be there at all.

For each tab that you have visited (that is not the current tab) it will call onAppear and onDisappear for it when the tab view is removed.

SwiftUI bug, when removing a TabView all other tabs have `onAppear` and `onDisappear` triggered
 
 
Q