SwiftUI中为自定义按钮添加NavigationLink的跳转问题
一、编译错误的解决
你遇到的编译错误是因为NavigationLink的destination参数要求传入一个返回目标视图实例的闭包(类型为() -> Destination),但你传入的Signup是视图类型而非实例。
修改方式很简单:将destination: Signup替换为destination: Signup()(或者显式闭包形式destination: { Signup() }),这样就传入了正确的视图实例构造逻辑。
二、点击按钮不跳转的解决
你修改代码后点击无响应,核心原因是自定义按钮的点击闭包拦截了NavigationLink的默认点击事件。NavigationLink的label视图本身自带跳转触发逻辑,但如果给label内的控件添加了自定义onTapGesture或点击闭包,会覆盖原有的跳转行为。
有两种可行的解决方式:
方式1:通过绑定状态控制跳转(推荐用于需要自定义点击逻辑的场景)
将NavigationLink设为隐藏状态,通过修改绑定的isShowingSignupView值触发跳转,自定义按钮只负责修改状态:
@State private var isShowingSignupView = false var body: some View { NavigationView { VStack { Spacer() VStack(alignment: .center, spacing: 12) { AppTextField(Constants.Email, text: $email) AppTextField(Constants.Password, text: $password, isSecure: $isSecure, leftImage: "lock",rightImage: Image(systemName: "eye.fill"), rightSelectedImage: Image(systemName: "eye.slash.fill")) AppButtonText(title: Constants.ForgotPassword) { debugPrint("Forgot Password tapped") } .frame(maxWidth: .infinity, maxHeight: 20, alignment: .trailing) AppButton(title: Constants.Login) { } } Spacer() // 自定义按钮,点击修改绑定状态 AppButtonText(title: Constants.SignUp) { isShowingSignupView = true } // 隐藏的NavigationLink,由绑定状态控制跳转 NavigationLink(isActive: $isShowingSignupView) { Signup() } label: { EmptyView() } } .padding() } .navigationTitle("Login") }
方式2:移除自定义按钮的点击闭包
如果你的AppButtonText仅用于展示可点击文本,不需要额外的点击逻辑,可以直接移除它的点击闭包,让NavigationLink的默认跳转逻辑生效:
NavigationLink(destination: Signup()) { AppButtonText(title: Constants.SignUp) // 去掉后面的闭包参数 }
额外检查
确保Signup是一个正确实现了View协议的结构体,比如它有合法的body属性,否则即使跳转逻辑正确,也无法展示目标页面。
内容的提问来源于stack exchange,提问作者Sanket Parmar
相关产品推荐
相关产品推荐

