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

SwiftUI如何实现API请求成功后才跳转至新视图?

实现SwiftUI条件式导航:API成功获取有效数据后再跳转

当前代码里的NavigationLink会在点击时直接跳转,异步API调用的结果没法影响跳转时机。要实现仅在API调用成功且数据有效时才跳转,可以通过手动控制导航激活状态的方式解决,具体步骤如下:

1. 新增导航状态变量

在LoginView里添加一个@State变量,用来控制导航是否激活:

@State private var shouldNavigate = false

2. 拆分导航逻辑

把原来的NavigationLink拆成两部分:

  • 一个普通按钮:负责触发API调用,等待结果并验证数据
  • 一个隐藏的NavigationLink:通过isActive绑定shouldNavigate,仅在状态为true时触发跳转

3. 调整ViewModel状态

在ViewModel里新增一个标记数据有效性的属性,方便View判断是否可以跳转:

class ViewModel: ObservableObject {
    @Published var isDataValid = false // 标记API返回数据是否有效
    
    func fetchPlayerData() async {
        // 实际API请求逻辑
        do {
            let response = try await yourAPICall()
            // 根据业务需求验证数据
            self.isDataValid = self.validateResponse(response)
        } catch {
            self.isDataValid = false
        }
    }
    
    // 数据验证逻辑,根据实际需求实现
    private func validateResponse(_ data: YourDataType) -> Bool {
        return data.requiredField != nil // 示例:检查关键字段是否存在
    }
}

4. 修改LoginView完整代码

import SwiftUI

struct LoginView: View {
    @ObservedObject var vm: ViewModel
    @State private var username = ""
    @State private var shouldNavigate = false // 控制导航激活状态
    
    // 修正原逻辑:原代码是用户名长度>2时禁用按钮,若逻辑反了可改成 return username.count > 2
    private var searchAllowed: Bool {
        username.count <= 2
    }
    
    var body: some View {
        NavigationView {
            VStack {
                Text("Enter your Username:")
                    .font(.title.bold())
                
                TextField("Username", text: $username)
                    .frame(width: 280)
                    .padding(.bottom)
                
                // 触发API调用的按钮
                Button(action: {
                    Task {
                        await vm.fetchPlayerData()
                        // 数据有效才触发跳转
                        if vm.isDataValid {
                            shouldNavigate = true
                        }
                    }
                }) {
                    ZStack {
                        RoundedRectangle(cornerRadius: 5)
                            .fill(.gray)
                            .frame(width: 200, height: 50)
                        
                        Text("Search")
                            .foregroundColor(.white)
                    }
                }
                .disabled(searchAllowed)
                
                // 隐藏的导航链接,由shouldNavigate控制跳转
                NavigationLink(
                    destination: ProfileView(vm: vm),
                    isActive: $shouldNavigate
                ) {
                    EmptyView()
                }
                .hidden()
            }
        }
    }
}

核心逻辑说明

  • 点击按钮后先执行异步API调用,等待请求完成
  • 根据ViewModel返回的isDataValid状态,决定是否设置shouldNavigate = true
  • 隐藏的NavigationLink会在shouldNavigate变为true时自动触发跳转,实现了条件式导航

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:18:16