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

如何让ScrollView中的NavigationLink实现List式点击高亮效果?

问题描述

我发现List和Form的功能无法满足需求,只能在ScrollView里构建传统UI。在List中使用NavigationLink时,点击链接会在跳转前展示整个单元格的动画高亮效果,但在ScrollView里用NavigationLink时做不到这点:

  • 必须用.contentShape()才能让整个单元格可点击,而不是只有内容区域
  • 点击高亮只作用于单元格内的Text、Image等内容,整个单元格背景不会变化

点击前:
点击前

点击时:(注意单元格背景无变化)
点击时

核心问题:如何让ScrollView中的NavigationLink实现List单元格样式的点击动画效果?

原代码:

struct TestCellView: View {

    var body: some View {
        ScrollView {
            GroupBox {
                NavigationLink(destination: Text("Some detail view")) {
                    HStack {
                        Text("FAQ")
                        Spacer()
                        Image(systemName: "chevron.right")
                            .foregroundColor(.secondary)
                    }
                    .contentShape(Rectangle()) // Required to make whole button tappable.
                }
                .buttonStyle(.plain) // Remove system tinting on the Text and Image.
            }
        }
        .padding()
        .navigationTitle("Test")
        .navigationBarTitleDisplayMode(.inline)
    }
}


#Preview {
    NavigationStack {
        TestCellView()
            .preferredColorScheme(.dark)
    }
}
解决方案

要实现List单元格的点击高亮效果,可以通过以下方式修改代码:

  1. 让NavigationLink的内容容器占满整个单元格空间,确保点击区域覆盖全部范围
  2. 自定义按钮样式,模拟List单元格的点击高亮动画

修改后的代码:

struct TestCellView: View {
    var body: some View {
        ScrollView {
            GroupBox {
                NavigationLink(destination: Text("Some detail view")) {
                    HStack {
                        Text("FAQ")
                        Spacer()
                        Image(systemName: "chevron.right")
                            .foregroundColor(.secondary)
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                    .padding()
                }
                .buttonStyle(ListCellButtonStyle())
            }
        }
        .padding()
        .navigationTitle("Test")
        .navigationBarTitleDisplayMode(.inline)
    }
}

// 自定义按钮样式,模拟List单元格的点击高亮
struct ListCellButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .background(configuration.isPressed ? Color(.systemGray5) : Color.clear)
            .cornerRadius(8)
    }
}

#Preview {
    NavigationStack {
        TestCellView()
            .preferredColorScheme(.dark)
    }
}

关键说明:

  • .frame(maxWidth: .infinity, maxHeight: .infinity)让内容容器占满GroupBox的全部空间,无需额外设置.contentShape()就能实现全单元格点击
  • 自定义ListCellButtonStyle在按钮按下时切换背景色,还原List单元格的高亮动画逻辑
  • 移除.buttonStyle(.plain),通过自定义样式控制点击状态,同时保留原有内容的视觉样式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:13:12