Infinite Loop Issue with View's onAppear and onDisappear in iOS 17 Beta

While testing my application on iOS 17 beta, I encountered an issue where the onAppear and onDisappear functions of the View inside the List went into an infinite loop, rendering the application inoperable. This did not occur with iOS 16 or iOS 15.

Is this a bug with the iOS 17 beta? Or did the specifications change with iOS 17?

Here is the reproduction code. On iOS 17 beta, as soon as the application starts, the onAppear and onDisappear of SampleSection go into an infinite loop.

Testing Environment:

Xcode: Version 14.3.1 (14E300c), Version 15.0 beta 3 (15A5195k)

Device: iPhone SE (2nd) iOS 15.2, iPhone SE (3rd) iOS 16.4, iPhone SE(3rd) iOS17 beta 3


import SwiftUI

@main
struct SampleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        List {
            SampleSection()
            section // This issue occurs even without this line.
        }
    }
    
    private var section: some View {
        Section {
            ForEach(1...100, id: \.self) { idx in
                Text("\(idx)")
            }
        }
    }
}

struct SampleSection: View {
    @State private var isLoaded = false
    var body: some View {
        let _ = Self._printChanges()
        Group {
            if !isLoaded {
                Section("Header") {}
                    .hidden()
            } else {
                Section("Header") {
                    Text("Text")
                }
            }
        }
        .onAppear {
            NSLog("SampleSection onAppear.")
            isLoaded = true
        }
        .onDisappear() {
            NSLog("Sample Section onDisappear.")
            isLoaded = false
        }
    }
}

I've posted feedback. FB12552709

Here is a workaround for this issue in the reproduction code.

struct SampleSection: View {
    @State private var isLoaded = false
    var body: some View {
        let _ = Self._printChanges()
        if !isLoaded {
            Section("Header") {}
                .hidden()
                .onAppear {
                    NSLog("SampleSection onAppear.")
                    isLoaded = true
                }
        } else {
            Section("Header") {
                Text("Text")
            }
            .onDisappear() {
                NSLog("Sample Section onDisappear.")
                isLoaded = false
            }
        }
    }
}

In my app, the above workaround caused another problem. But, I could avoid it by changing the next code using DispatchQueue.main.async.

I hope this issue will be resolved by the public release of iOS 17.

struct SampleSection: View {
    @State private var isLoaded = false
    var body: some View {
        let _ = Self._printChanges()
        Group {
            if !isLoaded {
                Section("Header") {}
                    .hidden()
            } else {
                Section("Header") {
                    Text("Text")
                }
            }
        }
        .onAppear {
            DispatchQueue.main.async { // or Task { @MainActor in
                NSLog("SampleSection onAppear.")
                isLoaded = true
            }
        }
        .onDisappear() {
            DispatchQueue.main.async { // or Task { @MainActor in
                NSLog("Sample Section onDisappear.")
                isLoaded = false
            }
        }
    }
}

Infinite Loop Issue with View's onAppear and onDisappear in iOS 17 Beta
 
 
Q