App killed in the background with NavigationSplitView on iOS 16

Description

We have a sidebar-detail layout in our app. Since we moved from NavigationView on iOS 15 to NavigationSplitView on iOS 16, we've seen some issues.

  • On iOS 16, the app is always killed, or reset, when the app enters background. That means whatever the sidebar and detail view show, they will almost always return to the initial blank screen state when coming back from background.
  • On iOS 17, the background issue is mitigated. However, the toolbar button is missing after coming back from background.

Those problem aren't present in NavigationView on iOS 15.

Steps to Repro

General steps…

  1. Create a new iOS app demo project with deployment target min version set to iOS 16.
  2. Copy and paste the code snippet below into ContentView.swift.
  3. Run the app on iPad simulator with the respective Simulator OS versions.

iOS 16

  1. Tap the info button on the side bar, it presents a "form sheet" style page.
  2. Put the app into background.
  3. Open any app. I opened the Photos app.
  4. Switch back to the demo app. The sheet is dismissed and the app returns to the initial state, which indicates the app was reset in the background.
  5. When I tap the info button again, it doesn't present a sheet.

iOS 17

  1. Same steps as 1-3 above for iOS 16.
  2. Switch back to the test app. The sheet is not dismissed, which means the app wasn't reset in the background.
  3. However, you can see the info button is missing from the sidebar's top toolbar.

Similar Posts

Repro Code Snippet

import SwiftUI

struct ContentView: View {
    let samples = ["foo", "bar"]
    
    var body: some View {
        NavigationSplitView {
            NavigationStack {
                sidebar
            }
        } detail: {
            NavigationStack {
                detail
            }
        }
    }
    
    var sidebar: some View {
        Sidebar(samples: samples)
    }
    
    var detail: some View {
        Text("Select a sample from the list.")
    }
}

struct Sidebar: View {
    @State private var isPresented = false
    
    let samples: [String]
    
    var body: some View {
        List {
            ForEach(samples, id: \.self) { sample in
                Text(sample)
            }
        }
        .navigationTitle("Foo")
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button("Info") {
                    isPresented = true
                }
                .sheet(isPresented: $isPresented) {
                    AboutView()
                }
            }
        }
    }
}

struct AboutView: View {
    @Environment(\.dismiss) private var dismiss: DismissAction
    
    var body: some View {
        NavigationStack {
            List {
                Text("Copyright © 2023 Foo. All Rights Reserved.")
            }
            .navigationTitle("About")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .confirmationAction) {
                    Button("Done") {
                        dismiss()
                    }
                }
            }
        }
    }
}

Replies

Hi @cht1995 , thanks so much for posting this! Please file a bug report at https://feedbackassistant.apple.com and post the feedback number here. Please include a sample project containing the above code (thank you for including that in your question).

  • FB13468078, attached demo project in FB.

Add a Comment