SwiftUI中如何根据API响应显示/隐藏视图?
解决SwiftUI中API请求完成后再判断视图显示的问题
问题根源
你的代码存在两个核心问题,导致视图无法正确响应API数据更新:
- 属性包装器误用:在
ObservableObject类中,你用@State标记totalApprovalCount,但@State是专为SwiftUI视图设计的属性包装器,ObservableObject类需要使用@Published才能让属性变化通知视图刷新。 - 缺少异步状态管理: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
相关产品推荐
相关产品推荐

