SwiftUI点击导航分类项展示对应分类菜单的实现方法
问题根因
跳转ConsoleMenu时没有传入对应分类的主机数据,ConsoleMenu默认加载了全量主机数组,因此会展示所有条目。另外代码里有两处冗余错误:
- 子页面
ConsoleMenu嵌套了多余的NavigationView,SwiftUI导航栈仅需最外层保留一个导航容器,内层嵌套会导致导航栏显示异常 ConsoleMenu的导航标题写在了List的循环闭包内部,属于无效位置,无法正确显示分类名
修改方案
- 调整
ConsoleMenu的结构:新增两个入参分别接收分类名称、对应分类下的主机列表,移除全量数据的默认赋值,删掉内层多余的NavigationView,将导航标题移到正确位置 - 调整
MainMenu的跳转逻辑:遍历分类字典时,将当前条目的分类名、对应主机数组作为参数传入目标页面 - 修正预览代码,传入测试参数保证预览正常运行
修改后的ConsoleMenu代码
import SwiftUI struct ConsoleMenu: View { // 接收外部传入的分类参数,不再默认加载全量主机数据 let categoryName: String let filteredConsoles: [ConsoleDetails] var body: some View { List(filteredConsoles, id:\.id) { cons in NavigationLink(destination: ConsoleDetailView(con: cons)) { Image(cons.imgName) .resizable() .scaledToFit() .frame(height: 50) .cornerRadius(4) .padding(.vertical, 4) VStack(alignment: .leading) { Text(cons.consoleName) .fontWeight(.semibold) } } } .navigationTitle(categoryName) } } struct ConsoleSection_Previews: PreviewProvider { static var previews: some View { NavigationView { ConsoleMenu( categoryName: "Home Consoles", filteredConsoles: [ ConsoleDetails( imgName: "FAMICOM", consoleName: "Famicom", description: "It was released in 1983 in Japan and due to it success it gave birth to the NES", initialPrice: 179, ReleaseDate: "Release Date: July 15, 1983", Discontinuation: 2003, category: "Home Consoles" ) ] ) .preferredColorScheme(.dark) } } }
修改后的MainMenu跳转逻辑
MainMenu其余代码保持不变,仅需要修改NavigationLink的跳转目标,传入对应参数即可:
List(ConsoleList.categories.sorted(by: {$0.key > $1.key}), id:\.key) { category in NavigationLink( destination: ConsoleMenu( categoryName: category.key, filteredConsoles: category.value ) ) { Image(systemName: "folder.fill") .scaledToFit() .frame(height: 30) .cornerRadius(4) .padding(.vertical, 4) VStack(alignment: .leading) { Text(category.key) .fontWeight(.semibold) } } } .navigationTitle("app.name")
补充说明
你之前通过Dictionary(grouping: consoles, by: {$0.category })生成的分类字典,遍历得到的每个元素的key就是分类名称,value就是该分类下匹配的所有主机对象,直接传入子页面即可,不需要额外编写过滤逻辑。
内容的提问来源于stack exchange,提问作者Techtronis
相关产品推荐
相关产品推荐

