每次我从 SwiftUI 的详细视图 return 时,如何阻止视图刷新?

How do I stop a view from refreshing each time I return from a detail view in SwiftUI?

我有一个显示 post 列表的视图。我已经实现了 infinite scrolling,它运行正常。然而,有一个小问题让我 运行 陷入困境,试图解决这个问题让我原地踏步。

主视图

struct PostsHomeView: View {

    @EnvironmentObject var viewModel: ViewModel
    @State var dataInitiallyFetched = false

    var body: some View {
    
        NavigationView {
        
             VStack(alignment: .center, spacing: 0) {

                 if self.viewModel.posts.count > 0  {
                         
                     PostsListView(posts: self.viewModel.posts,
                                  isLoading: self.viewModel.canFetchMorePosts,
                                  onScrolledAtBottom: self.viewModel.fetchMorePosts
                     )

                 } else {

                     VStack {
                         
                         Text("You have no posts!")
                         
                     }
                 }
             }
             .onAppear() {

                 if !self.dataInitiallyFetched {

                     self.viewModel.fetchMostRecentPosts()

                     self.dataInitiallyFetched = true
                 }
             }
             .navigationBarTitle("Posts", displayMode: .inline)
       }
    }
}

列表视图

struct PostsListView: View {
    
    @EnvironmentObject var viewModel: ViewModel      
    let posts: [Post]
    let isLoading: Bool
    let onScrolledAtBottom: () -> Void

    var body: some View {
       List {

           postsList
           
           if isLoading {
               loadingIndicator
           }
       }
    }
       
    private var postsList: some View {
               
       ForEach(posts, id: \.self) { post in

           PostsCellView(post: post)
               .onAppear {
                         
                   if self.posts.last == post {

                           self.onScrolledAtBottom()
                   }
               }
       }
       .id(UUID())
    } 
}

问题

点击列表中的 post 之一后,我将进入详细视图。当我点击导航栏的后退按钮返回 posts 列表时,整个视图会重新加载,我的 post 获取方法会再次触发。

为了停止触发获取最近 posts 的获取方法,我添加了一个标志,我在初始加载后将其设置为 true。当我在详细信息视图和 post 的主屏幕之间来回切换时,这会阻止获取初始集 post 的获取方法。

我尝试了各种方法来阻止 fetchMorePosts 函数启动,但我一直在兜圈子。我在我的视图模型中的 fetchMorePosts 函数的顶部添加了一个 guard 语句。它检查字符串是否等于“homeview”,如果不等于,则未完成获取。每当访问详细视图时,我都会将此字符串设置为“detailview”,然后在 guard 语句中将其重置回“homeview”。

guard self.lastView == "homeview" else {
    self.lastView = "homeview"
    return
}

这在一定程度上有效,但我不断发现它无法按预期工作的情况。必须有一种直接的方式告诉 SwiftUI 不要重新加载视图。问题是该方法位于 onAppear 闭包中,这对于无限滚动的工作至关重要。我还没有使用 iOS 14,所以我不能使用 @StateObject。

有没有办法告诉 SwiftUI 每次我从细节视图 return 时不要触发 onAppear

提前致谢

罪魁祸首是 .id(UUID())。我将它从我的列表中删除,然后一切又恢复正常了。

谢谢阿斯佩里。非常感谢您的帮助。