如何在子结构中重新加载当前视图的数据
Posted
技术标签:
【中文标题】如何在子结构中重新加载当前视图的数据【英文标题】:How to reload data of current view in sub-struct 【发布时间】:2020-07-19 19:31:51 【问题描述】:我的应用是电影应用。有一个SingleMovieView
可以展示一部电影的相关信息,比如
导演、演员……在底部,它是一个滚动视图,用于显示类似的电影列表。当用户单击其中一项时,应导航到选定的电影视图。
嗯,问题实际上是相同的SingleMovieView
目的地。或者说我想为所选电影重用这个视图和不同的数据。目前,我在RecMovieList
的 ForEach 中使用导航链接,并且录音不起作用。那么,如何在 SwiftUI 中对同一个 View 进行自调用呢?
代码如下:
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.secSectionMoviesBundle.isEmpty
Text("Loading")
else
VStack(alignment: .leading, spacing: 12)
CrewList(crews: (model.secSectionMoviesBundle[.Crew] as! [CrewViewModel]).filter $0.job == "Director" )
CastList(casts: model.secSectionMoviesBundle[.Cast] as! [CastViewModel])
ImageList(images: model.secSectionMoviesBundle[.Images] as! [ImageViewModel])
RecMovieList(movies: model.secSectionMoviesBundle[.Recomm] as! [MovieViewModel])
.edgesIgnoringSafeArea(.top)
.onAppear()
self.model.getMovieDetail(id: self.movieId)
self.model.getSecSectionMoviesBundle(id: self.movieId)
// struct CrewList
// struct CastList
// struct ImageList
struct RecMovieList: View
var movies: [MovieViewModel]
var body: some View
VStack(alignment: .leading)
Text("\(SecHomeSection.Recomm.rawValue)")
.font(.headline)
ScrollView(.horizontal)
HStack(alignment: .top, spacing: 10)
ForEach(0..<movies.count) i in
VStack(alignment: .leading)
NavigationLink(destination: SingleMovieView(movieId: self.movies[i].id))
KFImage(source: .network(self.movies[i].posterUrl))
.renderingMode(.original)
.resizable()
.frame(width: 100, height: 150)
.aspectRatio(2/3, contentMode: .fill)
Text("\(self.movies[i].title)")
.lineLimit(2)
.foregroundColor(.gray)
.frame(height: 50, alignment: .top)
.frame(width: 100)
//.frame(height: 100)
.padding(.horizontal).padding(.bottom)
fileprivate func createPosterImage() -> some View
return KFImage(source: .network(model.movie.posterUrl))
.resizable().aspectRatio(contentMode: .fit)
// 更新:,作为评论,我意识到这是当前视图的重新加载数据,而不是导航。所以我也将 ObservedObject 添加到 struct RecMovieList 中,然后现在发布的模型也可以在这个 struct 中使用,在 onAppear() 中重做网络请求。
我将 NavigationLink 更改为 Button,因为不需要导航。好吧,它可以工作并且视图可以重新加载,但是当我在应用程序中点击电影列表时,它会触发触摸事件/重新加载数据,即使是拖动、滑动也是如此。我该如何解决这个问题?使用 TapGesture?
struct RecMovieList: View
var movies: [MovieViewModel]
@ObservedObject var model = MovieListViewModel()
var body: some View
VStack(alignment: .leading)
Text("\(SecHomeSection.Recomm.rawValue)")
.font(.headline)
ScrollView(.horizontal)
HStack(alignment: .top, spacing: 10)
ForEach(0..<movies.count) i in
VStack(alignment: .leading)
Button(action:
self.model.getMovieDetail(id: self.movies[i].id)
self.model.getSecSectionMoviesBundle(id: self.movies[i].id)
)
KFImage(source: .network(self.movies[i].posterUrl))
.renderingMode(.original)
.resizable()
.frame(width: 100, height: 150)
.aspectRatio(2/3, contentMode: .fill)
Text("\(self.movies[i].title)")
.lineLimit(2)
.foregroundColor(.gray)
.frame(height: 50, alignment: .top)
.frame(width: 100)
//.frame(height: 100)
.padding(.horizontal).padding(.bottom)
【问题讨论】:
就我的观点而言:您应该将 self.model.movie 更改为所选电影。因为它是@Published(我想是的),你的视图应该被重新加载并更新为新电影。 我意识到它需要重新加载视图而不是导航。此问题已修复,请查看相关更新。但是我在更新中遇到了另一个问题,我可以再请你帮忙吗? 【参考方案1】:尝试用 NavigationView 覆盖 navigationLink()
NavigationView
NavigationLink(destination: DestinationView()) // code
如果没有帮助,也尝试覆盖整个“身体”
var body: some View
NavigationView
//code
更新:
尝试使用不同于默认按钮样式的推荐按钮图片
answer
.buttonStyle(BorderlessButtonStyle())
【讨论】:
感谢您的回答,我刚刚意识到我需要的是重新加载当前视图的数据,而不是导航,因为它已经在同一个视图中。我也更改了问题标题,避免任何误导。以上是关于如何在子结构中重新加载当前视图的数据的主要内容,如果未能解决你的问题,请参考以下文章
在 Django 中,如何单击按钮来调用视图然后重新加载页面