onAppear is called when the view hasn't appeared

I'm using a 100% SwiftUI app, currently on Xcode 12 Beta 4

In my ContentView, I have a simple TabView

Code Block swift
struct ContentView: View {
var body: some View {
TabView {
AgendaView()
.tabItem {
Image(systemName: "list.bullet")
Text("Agenda")
}
HealthView()
.tabItem {
Image(systemName: "heart")
Text("Health")
}
}
}
}


The AgendaView and HealthView have onAppear methods. On App launch, the AgendaView is the one visible, but onAppear is called for both AgendaView and HealthView.

Why is that? Shouldn't onAppear be called only when the view actually appears on screen?

Code for HealthView and AgendaView

Code Block swift
struct AgendaView: View {
var body: some View {
VStack {
Text("Hello, AgendaView!")
}.onAppear{
print("AgendaView.onAppear")
}.onDisappear(){
print("AgendaView.onDisappear")
}
}
}
struct HealthView: View {
var body: some View {
VStack {
Text("Hello, HealthView!")
}.onAppear{
print("HealthView.onAppear")
}.onDisappear(){
print("HealthView.onDisappear")
}
}
}




Post not yet marked as solved Up vote post of Khuffie Down vote post of Khuffie
14k views

Replies

As an update, this issue seems to only appear on device.

In the simulator of iOS 14, it works fine.
Further information
  • This only appears on actual devices, in the simulator, the issue does not appear.

  • The issue only appears with projects created with the SwiftUI App Life Cycle. The issue does not appear in projects with the UI Kit App Delegate Life Cycle projects.

I submitted a feedback: FB8285799

You can recreate this issue by creating a new project, choosing SwiftUI App from the Life Cycle dropdown, and replacing your ContentView with the following code.

If anyone has any thoughts on a workaround I'd appreciate it!

Code Block swift
import SwiftUI
struct ContentView: View {
var body: some View {
TabView {
AgendaView()
.tabItem {
Image(systemName: "list.bullet")
Text("Agenda")
}
HealthView()
.tabItem {
Image(systemName: "heart")
Text("Health")
}
SettingsView()
.tabItem {
Image(systemName: "gear")
Text("Settings")
}
}
}
}
struct AgendaView: View {
var body: some View {
VStack {
Text("Hello, AgendaView!")
}.onAppear{
print("AgendaView.onAppear")
}.onDisappear(){
print("AgendaView.onDisappear")
}
}
}
struct HealthView: View {
var body: some View {
VStack {
Text("Hello, HealthView!")
}.onAppear{
print("HealthView.onAppear")
}.onDisappear(){
print("HealthView.onDisappear")
}
}
}
struct SettingsView: View {
var body: some View {
VStack {
Text("Hello, SettingsView!")
}.onAppear{
print("SettingsView.onAppear")
}.onDisappear(){
print("SettingsView.onDisappear")
}
}
}


If it only appears on device then it is important to know what version of iOS your device is running. I can reproduce a similar problem on iOS 14b8 is that what you tried?

My Feedback is FB8689302
A TabView’s tab onAppear is erroneously called when the tab disappears when another is selected

And I referenced your feedback which sometimes helps get it resolved quicker.
Seeing this issue in the iOS14 release version as well.
Just for the record, I am experiencing this issue as well. I have a simple TabView:

Code Block
import SwiftUI
struct HomeTabbedView: View {
    var body: some View {
        TabView {
            RehearsalsView()
                .tabItem {
                    Image(systemName: "calendar.circle.fill")
                    Text("Rehearsals")
                }
            ProfileWrapperView()
                .tabItem {
                    Image(systemName: "person.crop.circle.fill")
                    Text("User Profile")
                }
        }
    }
}


The ProfileWrapperView consists of the following:

Code Block
import SwiftUI
struct ProfileWrapperView: View {
    @EnvironmentObject var portal: Portal
    @State var draftAdult: Adult = Adult.default
    
    var body: some View {
        if (portal.adult) != nil {
            ProfileEditView(adult: $draftAdult)
                .onAppear {
                    self.draftAdult = self.portal.adult!
                    print("ProfileEditView appearing")
                }
                .onDisappear {
                    self.portal.adult! = self.draftAdult
                    print("ProfileEditView disappearing")
                }
        } else {
            Text("No adult data found.")
        }
    }
}


When the user switches tabs from the User Profile tab to the Rehearsals tab, the onDisappear handler is called (expected) immediately followed by the onAppear handler (unexpected). I'm looking into submitting a bug report now. (This will be my first time doing this, so wish me luck. :) If anyone has a workaround for this, please let me know.
Still experiencing this issue. Really hope they fix this.
This has been fixed with Xcode 12.1.1

onAppear now only is called, wenn the tab actually was selected.
This is an issue again with Xcode 12.2 and iOS 14.2 when using TabView with PageTabViewStyle.

.onAppear is called multiple times on the first tab, but only once after scrolling pages.
Can confirm, Xcode 12.2 and iOS 14.2 this bug appears. Also: the selection from TabView(selection: $XYZ) is updated after onAppear is called. Though this only happens on the first tab.
Any progress here? Is this fixed?
Any update about this issue?
Any update about this issue?
Still... Xcode 12.5 on an application with UI Kit App Delegate Life Cycle and iOS 13 as a target. tested in multiple devices and simulators.
Agreed. Still broke. Can this be fixed please?

I am seeing the same issue with Xcode 12.4 + Deployment target macOS 10.15