1
votes

I'm having a problem where when I close the app to send it to the background and then reopen it, it doesn't go to the last screen. Instead it seems to reset just like if the app were being opened from scratch.

I've included an example below. Run it on an iPad in landscape mode, select "Favorites". The details controller will show a red screen. Close the app to send it to the background, open any other app, then go back to the test app. You'll see that it reset itself to the green view. It should stay on the red view.

I've taken all of my code straight from the Fruta example project which doesn't have this behavior so I have no idea what's going on.

EDIT

I've made SideBar a standalone list like Asperi suggested, and I'm also now using SceneStorage as Apple recommends. Using SceneStorage solves the sidebar issue at first, but the core problem is still there when I'm multiple levels deep in a navigation stack.

In this updated example if you tap on Numbers in the sidebar, then select a row, leave the app, and come back after doing something else, the sidebar selection resets.

I have discovered that this is only a problem if your app supports multiple windows. If you uncheck that box none of this seems to be necessary.

The example below has the most recent code edits.

EDIT

I reached out to Apple Code Level Support and they re-debited my account telling me that my issue might be a bug and advised me to file a radar. I’m not entirely sure that it’s a framework bug though.

struct ContentView: View {
    #if os(iOS)
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    #endif
    
    var body: some View {
        #if os(iOS)
        if horizontalSizeClass == .compact {
            AppTabNavigation()
        } else {
            AppSidebarNavigation()
        }
        #else
        AppSidebarNavigation()
        #endif
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


// MARK: - AppTabNavigation
struct AppTabNavigation: View {
    @State private var selection: Tab = .menu

    enum Tab {
        case menu
        case favorites
        case rewards
        case recipes
    }
    
    var body: some View {
        TabView(selection: $selection) {
            NavigationView {
                Color.purple
            }
            .tabItem {
                Label("Menu", systemImage: "list.bullet")
                    .accessibility(label: Text("Menu"))
            }
            .tag(Tab.menu)
            
            NavigationView {
                Color.orange
            }
            .tabItem {
                Label("Favorites", systemImage: "heart.fill")
                    .accessibility(label: Text("Favorites"))
            }
            .tag(Tab.favorites)
            
            NavigationView {
                Color.red
            }
            .tabItem {
                Label("Numbers", systemImage: "book.closed.fill")
                    .accessibility(label: Text("Numbers"))
            }
            .tag(Tab.recipes)
        }
    }
}

enum NavigationItem: String {
    case menu
    case favorites
    case recipes
}

struct SideBar: View{
    @Binding var selection: String?
    
    var body: some View {
        List(selection: $selection) {
            NavigationLink(destination: Color.green, tag: NavigationItem.menu.rawValue, selection: $selection) {
                Label("Menu", systemImage: "list.bullet")
            }
            
            NavigationLink(destination: Color.red, tag: NavigationItem.favorites.rawValue, selection: $selection) {
                Label("Favorites", systemImage: "heart")
            }
            
            NavigationLink(destination: ListView(), tag: NavigationItem.recipes.rawValue, selection: $selection) {
                Label("Numbers", systemImage: "book.closed")
            }
        }
        .listStyle(SidebarListStyle())
    }
}


struct AppSidebarNavigation: View {
    @SceneStorage("ContentView.selection") private var selection: String?
    
    var body: some View {
        NavigationView {
            SideBar(selection: $selection)

            Text("Select a category")
                .foregroundColor(.secondary)
        }
    }
}

struct ListView: View{
    @SceneStorage("ListView.selection") private var selection: String?
    
    var body: some View{
        List(0..<20){ num in
            NavigationLink(destination: ListDetails(num: num), tag: num.description, selection: $selection) {
                Text(num.description)
            }
        }
    }
}


struct ListDetails: View{
    let num: Int
    
    var body: some View{
        Text(num.description)
            .font(.title)
    }
}
1
This was helpful but still doesn't solve my issue. Please see the edited question. - Richard Witherspoon

1 Answers

0
votes

Computable property sidebar reevaluated causing List rebuilding, use instead standalone view, like

enum NavigationItem {
    case menu
    case favorites
    case recipes
}

struct AppSidebarNavigation: View {
    
    @State private var selection: NavigationItem? = .menu
    @State private var presentingRewards = false
    
    
    var body: some View {
        NavigationView {
            SideBarView(selection: $selection)
            
            Text("Select a category")
                .foregroundColor(.secondary)
        }
    }
}

struct SideBarView: View {
    @Binding var selection: NavigationItem?
    
    var body: some View {
        List(selection: $selection) {
            NavigationLink(destination: Color.green, tag: NavigationItem.menu, selection: $selection) {
                Label("Menu", systemImage: "list.bullet")
            }
            .tag(NavigationItem.menu)
            
            NavigationLink(destination: Color.red, tag: NavigationItem.favorites, selection: $selection) {
                Label("Favorites", systemImage: "heart")
            }
            .tag(NavigationItem.favorites)
            
            NavigationLink(destination: Color.blue, tag: NavigationItem.recipes, selection: $selection) {
                Label("Recipes", systemImage: "book.closed")
            }
            .tag(NavigationItem.recipes)
        }
        .listStyle(SidebarListStyle())
    }
}