SwiftUI 视图展示前数据未更新、跳转新页面数据为空问题
SwiftUI网络请求数据未同步到跳转视图修复方案
核心问题原因
你的代码存在两个核心逻辑错误导致数据加载晚于视图渲染:
finished回调执行时机错误:当前finished()写在网络请求发起之前,点击按钮后直接触发页面跳转,完全没有等待网络数据返回- 状态更新线程错误:URLSession的网络回调默认在后台线程执行,SwiftUI要求所有状态变量更新必须在主线程执行,否则不会触发视图刷新
- 额外需注意:传递数据用的
lP/t/m变量必须声明为@State(当前视图内定义)或@Published(存放在ObservableObject视图模型中)的响应式属性,否则数据更新无法通知视图
修复步骤
1. 修正loadData方法
需调整回调位置、增加逃逸闭包标记、切换主线程更新数据:
// 给finished闭包加@escaping标记,因为要在异步回调中执行 func loadData(dT : String, finished: @escaping () -> Void) { let urlString = "https://myurl" + dT guard let url = URL(string: urlString) else { return } let task = URLSession.shared.dataTask(with: url, completionHandler: { [weak self] data, _, error in guard let data = data, error == nil else { return } var result: Simulation? do { result = try JSONDecoder().decode(Simulation.self, from: data) } catch { print("Failed : \(error)") } guard let final = result else { return } // 这里保留你原有逻辑,注意你原代码中`t = f`应该是取返回结果的对应字段,这里修正为从final取 let t = final.f // 切换到主线程更新状态变量,再执行回调 DispatchQueue.main.async { for ts in t { self?.lP.append(ts.lP!) self?.m.append(ts.m!) self?.t.append(ts.t!) } // 数据更新完成后再触发跳转 finished() } }) // 启动网络任务 task.resume() }
2. 可选优化
可在按钮点击后增加加载状态禁用按钮,避免用户重复点击触发多次请求和页面跳转。
内容的提问来源于stack exchange,提问作者Luke Tomlinson
相关产品推荐
相关产品推荐

