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

自定义isActive绑定的NavigationLink点击后持续高亮如何解决?

解决方案

问题根源

原有实现将整个自定义视图绑定在了NavigationLink的交互链上,Form/List 内的Cell会默认保持选中高亮状态,直到跳转完成或者其他Cell被选中。你拦截了跳转逻辑但没有重置Cell的选中状态,就会出现高亮一直保留的问题。

修复方案

推荐改用 Button处理点击逻辑 + 隐藏NavigationLink负责跳转 的组合实现,这是SwiftUI中实现条件跳转的标准方案,修改后代码如下:

@State var label: LocalizedStringKey
@State var onTap: (@escaping (Bool) -> Void) -> Void
@State private var transition: Bool = false
@State private var inProgress: Bool = false

var body: some View {
    Button {
        guard !inProgress else { return }
        inProgress = true
        onTap(complete)
    } label: {
        HStack {
            Text(label)
            Spacer()
            if inProgress {
                ProgressView().progressViewStyle(CircularProgressViewStyle())
            } else {
                Image(systemName: "chevron.right")
                    .font(Font.system(.footnote).weight(.semibold))
                    .foregroundColor(Color(UIColor.systemGray2))
            }
        }
    }
    .buttonStyle(PlainButtonStyle())
    .background(
        NavigationLink(destination: EmptyView(), isActive: $transition) { 
            EmptyView() 
        }
        .opacity(0)
    )
}

private func complete(success: Bool) {
    inProgress = false
    transition = success
}

方案说明

  • 点击交互完全交给Button处理,配合PlainButtonStyle可以完全还原原来的Cell视觉效果,点击后的短暂高亮会在手势结束后自动消失,不会一直保留
  • 隐藏的NavigationLink仅和transition状态绑定,不需要再拦截Binding的set方法,逻辑更简洁易维护
  • 点击时自动拦截重复请求,避免多次触发服务端调用

可选优化

如果需要和系统设置的效果完全对齐,可以在请求完成时添加触感反馈:

private func complete(success: Bool) {
    inProgress = false
    transition = success
    let generator = UINotificationFeedbackGenerator()
    if success {
        generator.notificationOccurred(.success)
    } else {
        generator.notificationOccurred(.error)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:45:02