【发布时间】:2020-10-24 12:23:11
【问题描述】:
我正在从 API 加载数据,并希望我的应用在加载后显示数据。
在我的视图模型文件中,代码如下: 它调用 WeatherService 来获取数据,并填充天气属性。在这种情况下,天气是一个结构。
class WeatherViewModel: ObservableObject {
let webService = WeatherService.shared
@Published var weather:Weather?
init() {
}
func getWeather() {
webService.getWeather { weather in
if let weather = weather {
self.weather = weather
}
}
}
}
在我的 SwiftUI 视图中,代码如下:
- 我将 View Model 的一个实例实例化为 ObservedObject
- 在inAppear中,我调用视图模型中的方法来获取数据
- 第一次启动屏幕(使用标签栏)时,我看到“正在加载天气...”并且它永远不会消失
- 如果我导航到不同的选项卡并返回,我会看到天气。我不知道这是来自旧 API 调用的数据,还是来自新 API 调用的数据。
struct WeatherView: View {
@ObservedObject var weatherViewModel = WeatherViewModel()
@State var areDetailsHidden = true
var body: some View {
VStack(alignment: .leading, spacing: 0) {
if(weatherViewModel.weather == nil) {
Text("Loading weather...")
} else {
Text("Display the weather here")
}
}
.onAppear{
self.weatherViewModel.getWeather()
}
}
}
奇怪的是,如果我从 onAppear 中删除 getWeather() 并将其添加到 View Model 的 init() 中,它会起作用(尽管由于某种原因 getWeather() 被调用了两次......)。但是,我希望每次加载屏幕时都刷新天气信息。
【问题讨论】:
-
您听到的问题是
weatherViewModel归WeatherView所有。当它发生变化时,会再次渲染视图,从而创建一个新的weatherViewModel并且您处于无限循环中;您需要将模型移出视图。 -
@UpholderOfTruth 做到了!我把weatherViewModel变成了一个环境对象并解决了它。我的印象是身体再次被渲染,并且属性保持原样。有趣的。如果您将此作为答案提交,我会将其标记为此类。