微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

数组更改时SwiftUI列表未更新

如何解决数组更改时SwiftUI列表未更新

vstack(spacing: 0){
    List{
        ForEach(postsData.fetchedPosts,id: \.postID) { post in
            SocialPostView(post: post,showAccount: self.$showAccount,fetchedUser: self.$fetchedUser)
                .padding(.vertical)
                .listRowInsets(EdgeInsets())
                .onAppear {
                    self.elementOnAppear(post)
            }
        }
    }
    .pullToRefresh(isShowing: $isShowing) {
        dispatchQueue.main.asyncAfter(deadline: .Now() + 1) {
            self.isShowing = false
            self.postsData.newFetch = true
            self.postsData.fetchPosts(userInfo: self.userInfo)
        }
    }
}
private func elementOnAppear(_ post: Post) {
    /* onAppear on the view is called when a view appears on screen.
     elementOnAppear asks the view model if the element is the last one.
     If so,we ask the view model to fetch new data. */
    
    if self.postsData.isLastPostInList(post: post) {
        self.postsData.fetchPosts(userInfo: self.userInfo)
    }
}

当每个列表元素出现时,它会检查它是否是数组中的最后一个元素。如果是这样,它将从Firestore获取更多信息并更新fetchedPosts。但是,当数组更新时,列表不会更新,因此不会显示新元素。

这是ObservableObject,它发布数组。

class SocialObservable: ObservableObject{
    let db = Firestore.firestore()
    
    let objectwillChange = ObservableObjectPublisher()
    
    @Published var fetchedPosts = [Post]()
    
    @Published var lastSnap : DocumentSnapshot?
    @Published var reachedEnd = false
    
    var currentListener: ListenerRegistration?
    
    var newFetch = false {
        willSet{
            objectwillChange.send()
        }
    }
    
    init(userInfo: UserData){
        print(userInfo.uid)
        fetchPosts(userInfo: userInfo)
    }
    
    func fetchPosts(userInfo: UserData){
        var first: Query?
        
        if lastSnap == nil || newFetch {
            //not last snapshot,or just updated Feed
            
            if newFetch{
                newFetch.toggle()
                fetchedPosts = [] // clean up if new fetch
            }
            
            first = db.collection("posts")
                .whereField("availability",arrayContains: userInfo.uid)
                .order(by: "date",descending: true)
                .limit(to: 1)
        }
        else {
            first = db.collection("posts")
                .whereField("availability",descending: true)
                .start(afterDocument: lastSnap!)
                .limit(to: 1)
        }

        first?.getDocuments(completion: { (snapshot,error) in
            guard let snapshot = snapshot else {
                print("Error: \(error.debugDescription)")
                return
            }
            let doc = snapshot.documents.map({postFromDB(obj: $0.data(),id: $0.documentID)})
            
            doc.map({print($0.postID)})
            // append to fetched posts
            self.fetchedPosts = self.fetchedPosts + doc
            print(self.fetchedPosts.count)
            
            //prepare for the next fetch
            guard let lastSnapshot = snapshot.documents.last else {
                // the collection is empty. no data fetched
                self.reachedEnd = true
                return
            }
            // save last snapshot
            self.lastSnap = lastSnapshot
        })
        
        
    }
    
    
    
    func isLastPostInList(post: Post) -> Bool {
        return post.postID == fetchedPosts.last?.postID
    }
    
    
}

有什么解决方法吗?

解决方法

几件事

class SocialObservable: ObservableObject{
    let db = Firestore.firestore()
    
    // let objectWillChange = ObservableObjectPublisher()     // << remove this
    
    // ...
    
    var newFetch = false {
        willSet{
            self.objectWillChange.send()    // ObservableObject has default
        }
    }

    // ...

并在更新时修改发布在主队列上的

    doc.map({print($0.postID)})
    // append to fetched posts
    DispatchQueue.main.async {
       self.fetchedPosts = self.fetchedPosts + doc
    }
    print(self.fetchedPosts.count)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。