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

SwiftUI中如何根据API响应显示/隐藏视图?

解决SwiftUI中API请求完成后再判断视图显示的问题

问题根源

你的代码存在两个核心问题,导致视图无法正确响应API数据更新:

  1. 属性包装器误用:在ObservableObject类中,你用@State标记totalApprovalCount,但@State是专为SwiftUI视图设计的属性包装器,ObservableObject类需要使用@Published才能让属性变化通知视图刷新。
  2. 缺少异步状态管理:API请求是异步操作,视图初始化时totalApprovalCount默认值为0,此时直接判断条件必然不成立,你需要跟踪请求的加载状态,确保在请求完成后再执行视图判断。

修复方案

1. 修正ViewModel代码

将@State替换为@Published,新增加载状态、错误状态属性,同时修正代码笔误(rcCount应为定义的poCount):

class DashboardViewModel: ObservableObject {
    @Published var poCount: [TaskCount]?
    @Published var totalApprovalCount = 0
    @Published var isLoading = false
    @Published var error: Error?

    func getData() {
        isLoading = true
        error = nil
        
        APIService.shared.makeApiTypeRequest(
            url: APIURLConstant.poTaskCountUrl,
            param: nil,
            methodType: .get,
            expecting: [TaskCount].self,
            passToken: true
        ) { [weak self] result in
            guard let self = self else { return }
            DispatchQueue.main.async {
                self.isLoading = false
                switch result {
                case .success(let respData):
                    self.poCount = respData
                    print("fetchRCCount called \(respData.count)")
                    
                    // 重置计数避免重复累加
                    self.totalApprovalCount = 0
                    if respData.count > 0 {
                        self.totalApprovalCount += respData[0].count ?? 0
                    }
                    if respData.count > 1 {
                        self.totalApprovalCount += respData[1].count ?? 0
                    }
                case .failure(let error):
                    self.error = error
                    if error is CustomError, (error as! CustomError) == .tokenExpired {
                        // 此处添加token过期后的处理逻辑,如跳转登录页
                    }
                }
            }
        }
    }
}

2. 修正视图代码

根据加载状态、错误状态和totalApprovalCount显示对应内容:

struct DashboardCombinedView: View {
    @ObservedObject var dashboardModel = DashboardViewModel()
    
    var body: some View {
        VStack(spacing: 16) {
            // 加载中显示进度提示
            if dashboardModel.isLoading {
                ProgressView("加载中...")
            }
            // 加载失败显示错误信息
            else if let error = dashboardModel.error {
                Text("加载失败: \(error.localizedDescription)")
                    .foregroundColor(.red)
            }
            // 请求完成后判断显示自定义视图
            else {
                if dashboardModel.totalApprovalCount > 0 {
                    Text("My custom view")
                } else {
                    Text("暂无审批任务")
                }
            }
        }
        .onAppear() {
            dashboardModel.getData()
        }
    }
}

关键说明

  • @Published会在属性值变化时自动发送通知,触发视图刷新,确保API请求完成后totalApprovalCount的更新能被视图感知。
  • 新增的isLoading和error属性可以提升用户体验,避免用户看到无意义的空白或错误状态。
  • 计算totalApprovalCount前先重置为0,防止多次调用getData()时出现计数累加错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:40:23