SwiftUI 侧边栏无法记住屏幕

5
我遇到了这样的问题,当我关闭应用并将其发送到后台,然后重新打开它时,它不会返回到上一个屏幕。相反,它似乎像是从头开始打开应用一样重置了。
我在下面附上了一个示例。在横向模式下在iPad上运行它,选择“收藏夹”。详细信息控制器将显示为红色屏幕。关闭应用程序将其发送到后台,然后打开任何其他应用程序,再回到测试应用程序。您会看到它重置为绿色视图。它应该停留在红色视图上。
我已经全盘采用了Fruta示例项目中的所有代码,但没有这种行为,所以我不知道发生了什么。
编辑
我像Asperi建议的那样将SideBar作为独立列表,并且现在使用SceneStorage,正如Apple建议的那样。使用SceneStorage解决了侧边栏问题,但是当我在导航堆栈中处于多个级别深度时,核心问题仍然存在。
在此更新的示例中,如果您在侧边栏中点击Numbers,然后选择一行,在离开应用程序并进行其他操作后返回,则侧边栏选择将重置。
我发现只有当您的应用程序支持多个窗口时,才会出现此问题。如果取消选中该框,则似乎不需要执行任何操作。
下面的示例具有最新的代码编辑。
编辑
我联系了苹果代码级别支持,他们退回了我的账户并告诉我我的问题可能是一个bug,并建议我提交radar。但我并不完全确定这是一个框架bug。
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)
    }
}

有关SwiftUI状态恢复,请参阅https://developer.apple.com/documentation/uikit/view_controllers/restoring_your_app_s_state_with_swiftui。 - user1046037
1
这对我有帮助,但仍未解决我的问题。请查看编辑后的问题。 - Richard Witherspoon
1个回答

0

可计算属性sidebar被重新评估,导致List重建,请改用独立视图,例如:

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())
    }
}

1
这很有帮助,但仍然没有解决我的问题。请查看编辑后的问题。 - Richard Witherspoon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接