自定义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
相关产品推荐
相关产品推荐

