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

SwiftUI中如何在ViewModel收到API成功响应后触发视图关闭?

解决方案

核心思路

你的ViewModel是ObservableObject类型,可以通过@Published属性向视图同步状态,请求完成后修改状态触发视图的关闭逻辑,而非点击按钮时直接执行关闭。

步骤1:改造ViewModel

在ViewModel中新增一个Bool类型的@Published属性,网络请求成功后将其置为true。

class PageViewModel: ObservableObject {
    // 标记是否需要关闭当前页面
    @Published var shouldDismiss = false
    
    func fetchNetworkData() {
        // 原有网络请求逻辑
        WebService.shared.requestAPI { [weak self] result in
            guard let self = self else { return }
            // 必须切回主线程更新UI相关属性
            DispatchQueue.main.async {
                switch result {
                case .success(_):
                    // 请求成功,修改状态通知视图关闭
                    self.shouldDismiss = true
                case .failure(let error):
                    // 自定义错误处理逻辑,比如弹出提示
                    print(error.localizedDescription)
                }
            }
        }
    }
}

步骤2:在视图中监听状态变化

在视图中通过onChange修饰符监听上述属性的变化,当属性变为true时执行关闭操作。

struct TargetPageView: View {
    @Environment(\.presentationMode) var presentationMode
    @StateObject var viewModel = PageViewModel()
    
    var body: some View {
        Button("发起请求") {
            // 只触发请求逻辑,不要在这里调用dismiss
            viewModel.fetchNetworkData()
        }
        // 监听ViewModel的状态变化,满足条件时关闭页面
        .onChange(of: viewModel.shouldDismiss) { needDismiss in
            if needDismiss {
                presentationMode.wrappedValue.dismiss()
            }
        }
    }
}

优化说明

  • iOS 15及以上版本可以用更精简的关闭API:将环境变量替换为@Environment(\.dismiss) private var dismiss,关闭时直接调用dismiss()即可。
  • 如果页面可能被多次推入导航栈,执行关闭前可以先将shouldDismiss重置为false,避免重复触发关闭逻辑。

内容的提问来源于stack exchange,提问作者New iOS Dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:57:03