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

SwiftUI中如何先执行函数再进行页面导航?

适配iOS 16:先执行动作再完成页面导航的解决方案

问题根源

你之前把自定义FullWidthButton嵌套在NavigationLink里,导致两层可交互元素的触摸事件冲突——既丢失了按钮的原生触摸动画,也无法正确触发导航逻辑。而iOS 16已废弃带isActive参数的旧版NavigationLink,因此需要改用NavigationStack配合状态变量的方式实现需求。

实现步骤

  1. 切换到NavigationStack:iOS 16+推荐使用NavigationStack替代旧的NavigationView
  2. 新增导航控制状态:用@State变量标记是否需要触发导航
  3. 调整按钮点击逻辑:在业务函数执行完成后,根据结果设置导航状态
  4. 添加绑定导航状态的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:07:14