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

如何自定义NavigationLink中View的按压样式并禁用默认灰色状态

自定义NavigationLink按压状态并适配ScrollView滚动恢复

要实现自定义按压样式并在ScrollView滚动时自动恢复状态,只需通过以下几步修改代码:

1. 禁用NavigationLink默认按压样式

在NavigationLink上添加.buttonStyle(PlainButtonStyle()),完全移除系统默认的灰色高亮效果。

2. 用@GestureState管理按压状态

@GestureState是SwiftUI专门用于手势状态的属性包装器,当手势结束或被中断(比如ScrollView滚动)时,会自动将值重置为初始值,刚好满足滚动恢复的需求。

修改后的完整代码

struct Item: Identifiable {
    let id = UUID()
    let title: String
}

struct ContentView: View {
    let items = [Item(title: "One"), Item(title: "Two"), Item(title: "Three")]
    
    var body: some View {
        NavigationStack {
            ScrollView (showsIndicators: false) {
                ForEach(items) { item in
                    NavigationLink {
                        ItemDetailView(item: item)
                    } label: {
                        ItemView(item: item)
                    }
                    .buttonStyle(PlainButtonStyle()) // 禁用默认按压样式
                }
            }
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

struct ItemView: View {
    let item: Item
    @GestureState private var isPressed = false // 手势状态自动重置
    
    var body: some View {
        HStack {
            Text(item.title)
                .foregroundStyle(.purple)
                .multilineTextAlignment(.leading)
            
            Spacer()
        }
        .frame(maxWidth: .infinity)
        .padding()
        .background(isPressed ? .blue : .green)
        .clipShape(RoundedRectangle(cornerRadius: 10))
        .border(.red, width: isPressed ? 2 : 0)
        .padding(3)
        .simultaneousGesture(
            // 识别按压动作,最小距离0确保触摸即触发
            DragGesture(minimumDistance: 0)
                .onChanged { _ in
                    isPressed = true
                }
                .onEnded { _ in
                    isPressed = false
                }
        )
    }
}

struct ItemDetailView: View {
    let item: Item
    var body: some View {
        Text(item.title)
    }
}

关键说明

  • .buttonStyle(PlainButtonStyle()):彻底关闭NavigationLink的默认按压高亮,避免与自定义样式冲突。
  • @GestureState:替代普通@State,利用其手势中断自动重置的特性,无需额外监听ScrollView滚动事件,就能在用户开始滚动时恢复View的正常状态。
  • simultaneousGesture:确保自定义手势与NavigationLink的原生点击手势并行工作,既保留跳转功能,又能实时更新按压状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:39:51