SwiftUI:收藏列表取消收藏后详情页自动返回的解决方法
问题分析与解决方案
问题根源
当你在「收藏项目」页面时,列表的数据源是vm.filteredItems——这是一个动态计算的数组,会自动过滤掉未收藏的项目。当你在详情页取消当前项目的收藏后,savedItems更新,filteredItems会立即移除这个项目,导致原来的列表条目被销毁。由于NavigationLink绑定在该列表条目上,条目消失后SwiftUI会自动关闭对应的详情页。
简单解决方案
核心思路是让列表的数据源保持稳定,不随收藏状态变化直接移除条目,而是通过条件判断来显示/隐藏收藏的项目。这样即使项目被取消收藏,列表的数据源不会立即改变,NavigationLink对应的条目不会被销毁,详情页就不会自动退出。
修改ContentView中「收藏项目」列表的代码
将原来基于vm.filteredItems的遍历,改成基于全量vm.items的遍历,再通过vm.contains(entry)判断是否显示:
else if (selected == 2){ List{ // 遍历全量items,而非filteredItems ForEach(filterSearchText == "" ? vm.items : vm.items.filter({ $0.name.lowercased().contains(filterSearchText.lowercased()) }), id: \.id){ entry in // 仅显示收藏的项目 if vm.contains(entry) { HStack{ NavigationLink(destination: DetailView( thisBiase: $BiasStruct.biases[entry.id-1]), label: { Text("\(entry.name)") Image(systemName: vm.contains(entry) ? "heart.fill" : "heart") .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .trailing) .onTapGesture { vm.toggleFav(item: entry) } }) } } } } .searchable(text: $filterSearchText) .navigationTitle("Favorites") .cornerRadius(15) }
补充优化(可选)
你可以移除ViewModel中不再需要的filteredItems计算属性:
// 移除以下代码 // var filteredItems: [Biase] { // if showingFavs { // return items.filter { savedItems.contains($0.id) } // } // return items // }
方案有效性说明
全量vm.items是固定的数据源,不会随收藏状态变化增减元素。ForEach基于这个稳定的数据源生成列表条目,即使某个项目被取消收藏,只是对应的视图被隐藏,条目本身并没有被销毁,因此绑定的NavigationLink依然有效,详情页不会被自动关闭。同时,用户返回列表时,该项目会自动隐藏,体验不受影响。
内容的提问来源于stack exchange,提问作者John Citrowske
相关产品推荐
相关产品推荐

