iOS 16 SwiftUI Navigation Stack:能否移除Company的index实现循环跳转
优化思路
完全可以移除Company结构体中的index字段,通过数组索引匹配+取模运算实现循环跳转,核心是利用Company已实现的Hashable协议定位当前元素在数组中的位置,再直接修改NavigationStack的path属性完成页面切换。
步骤1:精简Company结构体
删除冗余的index字段,保留必要的标识与数据字段:
struct Company: Identifiable, Hashable { var id = UUID() let name: String let address: String }
步骤2:更新数据源初始化
去掉初始化时的index参数:
let companies: [Company] = [ .init(name: "Apple", address: "Infinity Loop"), .init(name: "Facebook", address: "Hacker Way"), .init(name: "Google", address: "Mountain View") ]
步骤3:重构详情页跳转逻辑
删除无用的@State var index: Int = 0,在「Go Next」按钮的点击事件中,通过数组索引定位+取模运算实现循环:
Button { // 找到当前公司在数组中的位置 guard let currentIndex = companies.firstIndex(of: company) else { return } // 取模运算实现循环切换 let nextIndex = (currentIndex + 1) % companies.count // 更新导航栈路径,跳转到下一个公司页面 path = [companies[nextIndex]] } label: { Text("Go Next") }
如果需要显示当前元素的序号,同样通过firstIndex(of:)获取:
if let currentIndex = companies.firstIndex(of: company) { Text("\(currentIndex)") } else { Text("0") }
完整优化后代码
import SwiftUI struct Company: Identifiable, Hashable { var id = UUID() let name: String let address: String } struct ContentView: View { let companies: [Company] = [ .init(name: "Apple", address: "Infinity Loop"), .init(name: "Facebook", address: "Hacker Way"), .init(name: "Google", address: "Mountain View") ] @State var path: [Company] = [] var body: some View { VStack { NavigationStack(path: $path) { List(companies, id: \.self) { company in NavigationLink(company.name, value: company) } .navigationDestination(for: Company.self) { company in VStack { // 显示当前元素序号 if let currentIndex = companies.firstIndex(of: company) { Text("\(currentIndex)") } else { Text("0") } Text(company.address) Button { guard let currentIndex = companies.firstIndex(of: company) else { return } let nextIndex = (currentIndex + 1) % companies.count path = [companies[nextIndex]] } label: { Text("Go Next") } Button { path.removeAll() } label: { Text("Go Home") } } } } } .padding() } }
关键说明
- Hashable协议的作用:因为
Company实现了Hashable,firstIndex(of:)可以精准匹配当前元素在数组中的位置,无需依赖自定义index字段。 - 取模运算实现循环:
(currentIndex + 1) % companies.count确保索引走到最后一个元素时,加1后取模会回到0,完美实现循环切换。 - 直接操作path:通过修改
path数组为下一个Company实例,NavigationStack会自动处理页面跳转与栈更新,符合iOS 16导航栈的设计逻辑。
内容的提问来源于stack exchange,提问作者Daryl Wong
相关产品推荐
相关产品推荐

