我在SwiftUI中遇到了一个奇怪的现象。在下面的代码中,onAppear()中的语句用于从JSON API获取数据。我将在主体视图中使用数据,特别是createSecCollectionView()
函数。
当我运行应用程序并触发该视图时,我看到if-else语句都在createSecCollectionView
中被触发,因此我简化了代码以在此处使用文本视图。首先,该值为nil,然后获取该值。
我的问题是我发现在onAppear
中进行api调用后,观察到的模型已获取了数据。但是createSecCollectionView()
没有得到。它什么也没显示。
那么,主体视图和onAppear的执行顺序是什么?据我了解,onAppear
就像前一个viewDidAppear
一样,它应该在出现正文视图之前运行(检索数据)。
在控制台中
name is empty
name has a value
import SwiftUI
import KingfisherSwiftUI
struct SingleMovieView: View {
var movieId: Int = -1
@ObservedObject var model = MovieListViewModel()
var body: some View {
ScrollView(showsIndicators: false) {
VStack(alignment: .leading) {
createPosterImage()
MovieDetailView(movie: self.model.movie)
createSecCollectionView()
Text("ABC")
}
}.onAppear() {
self.model.getMovieDetail(id: self.movieId)
self.model.getSecSectionMoviesBundle(id: self.movieId)
}
}
fileprivate func createPosterImage() -> some View {
return KFImage(source: .network(model.movie.posterUrl))
.resizable().aspectRatio(contentMode: .fill)
}
fileprivate func createSecCollectionView() -> some View {
if (model.secSectionMoviesBundle[.Cast]?[2] as? CastViewModel)?.name == nil {
print("name is empty")
return Text("Empty")
} else {
print("name has a value")
return Text( String( (model.secSectionMoviesBundle[.Cast]?[0] as? CastViewModel)?.name ?? "haibo" ) )
}
}
}
//更新:今天早上我发现了问题!要解决此问题,需要在主体视图内部调用createSecCollectionView()
之前,而不是在createSecCollectionView()
内部调用之前,添加空条件检查。然后,该函数可以返回包含数据的视图。
老实说,当我修复它时,事情立即在我的脑海中跳了出来。因此,createPosterImage()
和MovieDetailView(movie: self.model.movie)
之类的其他视图不需要进行空检查的原因,createSecCollectionView()
返回一个数组,它是一个UIViewRepresentable类型的视图,它表示UIKit视图,这可能是原因...
var body: some View {
ScrollView(showsIndicators: false) {
VStack() {
createPosterImage()
MovieDetailView(movie: self.model.movie)
Text("ABC")
}
if model.secSectionMoviesBundle.isEmpty {
Text("Loading...")
} else {
createSecCollectionView()
}
}.onAppear() {
self.model.getMovieDetail(id: self.movieId)
self.model.getSecSectionMoviesBundle(id: self.movieId)
}
}