点击 NavigationSplitView 上的不同按钮时如何避免重建视图

Bas*_*sil 5 swiftui swiftui-navigationlink swiftui-navigationsplitview swiftui-navigationstack

我尝试过苹果示例 为您的 SwiftUI 应用程序带来强大的导航结构

所以我的代码看起来像这样

        NavigationSplitView(
            columnVisibility: $navigationModel.columnVisibility
        ) {
            List(
                categories,
                selection: $navigationModel.selectedCategory
            ) { category in
                NavigationLink(category.localizedName, value: category)
            }
            .navigationTitle("Categories")
            .toolbar {
                ExperienceButton(isActive: $showExperiencePicker)
            }
        } detail: {
            NavigationStack(path: $navigationModel.recipePath) {
                RecipeGrid(category: navigationModel.selectedCategory)
            }
        }
Run Code Online (Sandbox Code Playgroud)

详情查看

struct RecipeGrid: View {
    var category: Category?
    var dataModel = DataModel.shared

    var body: some View {
        ZStack {
            if let category = category {
                ScrollView {
                    LazyVGrid(columns: columns) {
                        ForEach(dataModel.recipes(in: category)) { recipe in
                            NavigationLink(value: recipe) {
                                RecipeTile(recipe: recipe)
                            }
                            .buttonStyle(.plain)
                        }
                    }
                    .padding()
                }
                .navigationTitle(category.localizedName)
                .navigationDestination(for: Recipe.self) { recipe in
                    RecipeDetail(recipe: recipe) { relatedRecipe in
                        NavigationLink(value: relatedRecipe) {
                            RecipeTile(recipe: relatedRecipe)
                        }
                        .buttonStyle(.plain)
                    }
                }
            } else {
                Text("Choose a category")
                    .navigationTitle("")
            }
        }
    }

    var columns: [GridItem] {
        [ GridItem(.adaptive(minimum: 240)) ]
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我进入详细信息视图,然后点击其他侧边栏项目,然后返回到同一点击,它也会在显示切换时返回到根视图!这意味着视图确实重建了自己

在此输入图像描述

在 Apple News 应用程序上,它将保留在保存视图中,当我更改侧边栏项目时,它不会重建或返回到根视图

在此输入图像描述

我想要同样的行为,但我不知道该怎么做

我在这里没有找到任何问题,也没有任何文章解释如何执行与 Apple News 应用程序相同的行为

小智 1

我认为解决方案相当复杂。我尝试自己修改代码,但有\xe2\x80\x99s很多东西需要更改。

\n

首先,引起问题的原因是NavigationStack(path: $navigationModel.recipePath)每次用户点击侧边栏时,recipePath 都会重置。我希望我明白为什么,但我传递了一个手动绑定的路径Binding.init(get:set:)

\n

其次,该路线是[食谱],因此当您选择其他类别时,该路线将被清空。否则,当用户点击侧边栏时,上一个类别中的所选项目仍会显示。

\n

因此,您需要将路线设置为字典([类别:[食谱]]),并且需要保存每个类别的路线。

\n

在我进行此更改后,我在Apple文档中看到可以在视图出现后恢复路线,这可能解决了第一个问题。

\n

因此,每次类别发生变化时,我都会复制该类别的路线。然后,当再次点击该类别时,我尝试恢复它,但我被困在这里,因为 onAppear was\xe2\x80\x99t 在 上为我触发RecipeGrid(\xe2\x80\xa6).onAppear {}

\n