You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建匹配任意枚举关联值的NavigationLink?

问题:如何让NavigationLink匹配任意OnboardingRoute关联值?

用户定义了以下导航枚举:

enum NavRoute {
  case loggedOut
  case onboarding(OnboardingRoute)
   
  enum OnboardingRoute {
    case page1
    case page2
  }
}

@State var route = NavRoute.onboarding(.page1)

希望编写如下NavigationLink,让tag参数匹配任意OnboardingRoute类型的关联值:

NavigationLink(
  tag: NavRoute.onboarding(any), // 这里应该填什么?
  selection: $route
) {
  OnboardingView()
} label: {
  Text("Create account")
}

解决方案

Swift中NavigationLink的selection和tag匹配依赖精确的Equatable判断,默认情况下不同关联值的onboarding case会被视为不相等。要实现“匹配任意OnboardingRoute关联值”的需求,有两种常用方法:

方法1:自定义Equatable实现

让NavRoute遵循Equatable,并改写相等判断逻辑,只要两个case都是onboarding类型,就视为相等:

enum NavRoute: Equatable {
    case loggedOut
    case onboarding(OnboardingRoute)
   
    enum OnboardingRoute: Equatable {
        case page1
        case page2
    }
    
    static func == (lhs: NavRoute, rhs: NavRoute) -> Bool {
        switch (lhs, rhs) {
        case (.loggedOut, .loggedOut):
            return true
        case (.onboarding, .onboarding):
            // 忽略关联值,所有onboarding case视为相等
            return true
        default:
            return false
        }
    }
}

之后NavigationLink的tag可以填任意一个onboarding实例(比如.onboarding(.page1)),只要route是任意onboarding关联值,就会匹配成功:

NavigationLink(
  tag: NavRoute.onboarding(.page1),
  selection: $route
) {
  OnboardingView()
} label: {
  Text("Create account")
}

方法2:使用isActive绑定替代selection

如果不想修改枚举的Equatable逻辑,可以通过计算属性判断当前路由是否属于onboarding类型,用isActive绑定来控制NavigationLink:

@State var route = NavRoute.onboarding(.page1)

// 自定义绑定,判断当前是否处于onboarding路由
private var isOnboardingActive: Binding<Bool> {
    Binding(
        get: {
            if case .onboarding = route {
                return true
            }
            return false
        },
        set: { isActive in
            if !isActive {
                // 退出onboarding时切换到指定路由,比如loggedOut
                route = .loggedOut
            }
        }
    )
}

// 使用isActive的NavigationLink
NavigationLink(
    isActive: isOnboardingActive
) {
    OnboardingView()
} label: {
    Text("Create account")
}

内容的提问来源于stack exchange,提问作者joshuakcockrell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 11:40:29