SwiftUI中如何先执行函数再进行页面导航?
适配iOS 16:先执行动作再完成页面导航的解决方案
问题根源
你之前把自定义FullWidthButton嵌套在NavigationLink里,导致两层可交互元素的触摸事件冲突——既丢失了按钮的原生触摸动画,也无法正确触发导航逻辑。而iOS 16已废弃带isActive参数的旧版NavigationLink,因此需要改用NavigationStack配合状态变量的方式实现需求。
实现步骤
- 切换到
NavigationStack:iOS 16+推荐使用NavigationStack替代旧的NavigationView - 新增导航控制状态:用
@State变量标记是否需要触发导航 - 调整按钮点击逻辑:在业务函数执行完成后,根据结果设置导航状态
- 添加绑定导航状态的
NavigationLink:通过状态变量控制导航的触发
修改后的完整代码
LoginView 代码
struct LoginView: View { let K = Constants() @State private var email: String = "" @State private var shouldNavigateToHome = false // 新增导航控制状态 var body: some View { NavigationStack { // 替换为NavigationStack VStack(alignment: .leading) { // 其他UI组件 CustomTextField( email: $email, imageName: "envelope", placeholder: "Enter e-mail address" ) // 其他UI组件 FullWidthButton( btnLable: "Continue with Apple", onPressHandler: onAppleLogin, backlgroundColor: Color(K.black), prefixIconName: K.appleLogo ) FullWidthButton( btnLable: "Continue with Facebook", onPressHandler: onFaceBookLogin, backlgroundColor: Color(K.fbBlue), prefixIconName: K.fbLogo ) Spacer() // 直接使用自定义按钮,不再嵌套NavigationLink FullWidthButton( btnLable: "Continue", onPressHandler: onContinuePress, backlgroundColor: Color(K.primary) ) // 隐藏的NavigationLink,通过状态变量控制导航 NavigationLink( destination: HomeView(), isActive: $shouldNavigateToHome, label: { EmptyView() } ) .hidden() } } } func onContinuePress() { // 1. 先执行你的业务逻辑(比如登录验证、请求接口等) print("执行登录逻辑...") // 2. 根据业务结果决定是否导航 // 示例:假设验证通过,触发导航 shouldNavigateToHome = true } // 补充其他登录方法的实现 func onAppleLogin() {} func onFaceBookLogin() {} }
FullWidthButton 代码(无需修改,保持原有触摸动画)
struct FullWidthButton: View { let K = Constants() var btnLable: String var onPressHandler: () -> Void var backlgroundColor: Color var prefixIconName: String? var body: some View { Button { onPressHandler() } label: { ZStack{ RoundedRectangle(cornerRadius: 27.0) .fill(backlgroundColor) .frame(height: 54) .padding(.horizontal) .overlay(alignment: .center) { HStack(alignment: .center) { if let imageName = prefixIconName { Image(imageName) } Text(btnLable) .font(.custom(K.poppins, size: 16)) .fontWeight(.medium) .foregroundColor(.white) } } } } .padding(.bottom) } }
关键说明
- 这种方式完全保留了自定义按钮的触摸动画,因为按钮不再被嵌套在其他可交互元素中
- 通过状态变量
shouldNavigateToHome可以灵活控制导航时机——你可以在业务逻辑(比如异步请求登录接口)完成后,再设置该变量为true触发导航 NavigationStack是iOS 16及以上版本的官方推荐导航容器,替代了旧版NavigationView,功能更强大且API更稳定
内容的提问来源于stack exchange,提问作者Rudra Soni
相关产品推荐
相关产品推荐

