SwiftUI:.sheet() 在关闭当前工作表时不会使用预期数据转到上一个视图

Posted

技术标签:

【中文标题】SwiftUI:.sheet() 在关闭当前工作表时不会使用预期数据转到上一个视图【英文标题】:SwiftUI: .sheet() doesn't go to the previous view with expected data when dismiss current sheet 【发布时间】:2020-04-11 04:23:01 【问题描述】:

至少,我的代码如下所示。在SinglePersonView 中,当用户在 MovieListView(显示演员参加的电影的电影列表)中点击一个电影图像时,它会以工作表模式打开SingleMovieView

工作表可以在点击时弹出。但我发现关闭工作表并在MovieListView 中重新选择其他电影后,工作表总是以我之前点击的电影信息即第一次选择的方式打开。我可以在控制台中看到,movie id 总是和第一次一样。我现在没有任何线索,我是否需要在解雇时进行一些重新加载操作或其他什么?

在 SwiftUI 的 subView 中使用 .sheet() 是正确的方法,还是应该始终将其保留在主体中,在这种情况下为 SinglePersonView

struct SinglePersonView: View 
  var personId = -1
  @ObservedObject var model = MovieListViewModel()

  var body: some View 
    ScrollView() 
      VStack() 
        ...
        MovieListView(movies: model.movies)
        ...
      
    .onAppear 
      // json API request
    
  


struct MovieListView: View 
  var movies: [PersonMovieViewModel]
  @State private var showSheet = false

  ScrollView() 
    HStack() 
      ForEach(movies)  movie in
        VStack() 
          Image(...)
          .onTapGesture 
              self.showSheet.toggle()
          
          .sheet(isPresented: self.$showSheet) 
              SingleMovieView(movieId: movie.id)
          
        
      
    
  



【问题讨论】:

【参考方案1】:

视图堆栈中应该只有一个 .sheet,但在提供的快照中,有许多会同时激活 - 实际上,以下行为是不可预测的。

这里是更正的变体

struct MovieListView: View 
    var movies: [PersonMovieViewModel]
    @State private var showSheet = false
    @State private var selectedID = ""         // type of your movie's ID

    var body: some View 
        ScrollView() 
            HStack() 
                ForEach(movies)  movie in
                    VStack() 
                        Image(...)
                            .onTapGesture 
                                self.selectedID = movie.id
                                self.showSheet.toggle()
                        
                    
                
            
            .sheet(isPresented: $showSheet) 
                SingleMovieView(movieId: selectedID)
            
        
    

【讨论】:

哦!我应该将.sheet 放在ForEach 循环之外,并将循环中的id 分配给State 属性。这解决了我的代码问题,谢谢!我发现我可以将.sheet放在scrollView之后并获得相同的效果,那么将.sheet放在Stack View或Scroll View之后有什么不同吗? 当然,我也更改了问题标题以与问题保持一致。

以上是关于SwiftUI:.sheet() 在关闭当前工作表时不会使用预期数据转到上一个视图的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 多张纸:关闭动画损坏

ScrollView 打破 .sheet 表示

SwiftUI禁止用户关闭sheet弹出视图在iOS14.6+失效的巧妙解决

SwiftUI禁止用户关闭sheet弹出视图在iOS14.6+失效的巧妙解决

iOS 16 中 SwiftUI 防止弹出的 sheet 视图被下滑关闭(dismiss)的新解决方案

iOS 16 中 SwiftUI 防止弹出的 sheet 视图被下滑关闭(dismiss)的新解决方案