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

SwiftUI的List单元格内能否放置多个NavigationLink?

问题原因

SwiftUI 默认会将 List 行内的所有 NavigationLink 绑定到整行的点击手势上,多个 NavigationLink 放在同一行时会出现手势冲突,点击任意位置都会触发跳转逻辑,最终表现不符合预期。

可行解决方案

不需要改用 LazyVStack,以下两种方案都可以完全保留 List 原生的侧滑操作、下拉刷新等特性:


方案1:添加独立按钮样式(适配iOS 15+,代码改动最小)

给每个 NavigationLink 加上独立的按钮样式,通知 List 不要将其合并到整行点击手势中,修正后的代码如下:

struct ContentView: View {
    var body: some View {
        NavigationView {
            
            List(0..<10) { index in
                HStack {
                    NavigationLink(destination: A()) {
                        Text("\(index) - Destination 1")
                    }
                    .buttonStyle(.borderless) // 关键配置

                    NavigationLink(destination: B()) {
                        Text("\(index) - Destination 2")
                    }
                    .buttonStyle(.borderless) // 关键配置
                } .padding()
            }
            // 原有侧滑、下拉刷新逻辑可以直接保留使用
        }
    }
}

方案2:隐藏NavigationLink配合点击事件(兼容iOS 13+)

如果需要兼容更低系统版本,可以用状态变量控制跳转目标,将NavigationLink隐藏在行背景中:

// 先定义跳转目标枚举
enum NavTarget {
    case a(Int)
    case b(Int)
}

struct ContentView: View {
    @State private var activeTarget: NavTarget?
    
    var body: some View {
        NavigationView {
            List(0..<10) { index in
                HStack {
                    Text("\(index) - Destination 1")
                        .onTapGesture {
                            activeTarget = .a(index)
                        }
                    
                    Text("\(index) - Destination 2")
                        .onTapGesture {
                            activeTarget = .b(index)
                        }
                }
                .padding()
                .background {
                    // 隐藏的导航链接
                    NavigationLink(isActive: Binding(
                        get: { activeTarget != nil },
                        set: { if !$0 { activeTarget = nil } }
                    )) {
                        switch activeTarget {
                        case .a(let index): A(index: index)
                        case .b(let index): B(index: index)
                        default: EmptyView()
                        }
                    } label: {
                        EmptyView()
                    }
                }
            }
        }
    }
}

两种方案均不需要修改你原有List相关的业务逻辑,可直接复用侧滑、下拉刷新等配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:15:01