在SwiftUI中重新加载当前View数据的正确方法是什么

时间:2020-04-12 03:40:29

标签: swiftui

这是我在SingleMovieView中的代码,它将显示一些电影列表,其中一个是RecMovieList。当用户点击RecMovieList中的电影图像之一,然后触发onTapGesture以重新加载模型中的数据(包括已发布的属性)时,它就起作用了。但是我的方法是将模型分配给RecMovieList。但我认为这不是合适的方法。

所以我想将其更改为以下内容:

  1. 删除了将模型属性分配给结构RecMovieList的操作。现在看起来像RecMovieList(movies: model.movieDetailBundle[.Recomm] as! [MovieViewModel])

  2. RecMovieList中,声明一个实例 型号var model = MovieListViewModel()

嗯,我认为由于已发布的模型数据源已更改,因此应该将数据重新加载到主体中,但是它不起作用;点按时不会重新加载数据。我搜索了很长时间,但还没有解决方案。那么,这两种方式有何不同?或者是在当前视图中重新加载数据的最佳方式是什么?

/ / / 更改前的工作代码。

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)

                if model.movieDetailBundle.isEmpty {
                    Text("Loading")
                }
                else {
                    VStack(alignment: .leading, spacing: 12) {
                        // CrewList(crews: (model.movieDetailBundle[.Crew] as! [CrewViewModel]).filter {$0.job == "Director"} )
                        // CastList(casts: model.movieDetailBundle[.Cast] as! [CastViewModel])
                        // ImageList(images: model.movieDetailBundle[.Images] as! [ImageViewModel])
                        RecMovieList(movies: model.movieDetailBundle[.Recomm] as! [MovieViewModel], model: self.model)
                    }
                }
            }
        }.edgesIgnoringSafeArea(.top)
        .onAppear() {
                self.model.getMovieDetail(id: self.movieId)
                self.model.getMovieDetailBundle(id: self.movieId)
        }
    }
    fileprivate func createPosterImage() -> some View {
        return KFImage(source: .network(model.movie.posterUrl))
            .resizable().aspectRatio(contentMode: .fit)
    }
}

// ...

struct RecMovieList: View {

    var movies: [MovieViewModel]
    var model: MovieListViewModel

    var body: some View {
        VStack(alignment: .leading) {
            Text("\(MovieDetailSection.Recomm.rawValue)")
                .font(.headline)
            ScrollView(.horizontal) {
                HStack(alignment: .top, spacing: 10) {
                    ForEach(movies) { movie in
                        VStack(alignment: .leading) {
                            KFImage(source: .network(movie.posterUrl))
                                .resizable()
                                .frame(width: 100, height: 150)
                                .aspectRatio(2/3, contentMode: .fill)
                                .onTapGesture {
                                    self.model.getMovieDetail(id: movie.id)
                                    self.model.getMovieDetailBundle(id: movie.id)
                                }
                            Text("\(movie.title)")
                            .lineLimit(2)
                            .foregroundColor(.gray)
                            .frame(height: 50, alignment: .top)

                        }.frame(width: 100)
                    }
                }
            }
        }
        .padding(.horizontal).padding(.bottom)
    }
}

0 个答案:

没有答案