我正在尝试使用Firestore对数据进行分页(无限滚动我的表 View )。我已经尽我所能集成了google给出的用于分页的代码,但是仍然无法正确加载数据。

初始数据集将根据需要加载到表 View 中。然后,当用户点击屏幕底部时,将加载下一个“x”项。但是,当用户第二次点击屏幕底部时,将相同的“x”项简单地附加到表中 View 。相同的项目会无限期地添加。

因此,其最初的3个“骑乘”对象,随后的4个“骑乘”对象将永远重复。

123 4567 4567 4567 4567 ...

如何获取正确加载的数据?

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offsetY = scrollView.contentOffset.y
    let contentHeight = scrollView.contentSize.height

    if offsetY > contentHeight - scrollView.frame.height {
        // Bottom of the screen is reached
        if !fetchingMore {
            beginBatchFetch()
        }
    }
}

func beginBatchFetch() {
    // Array containing "Ride" objcets is "rides"

    fetchingMore = true

    // Database reference to "rides" collection
    let ridesRef = db.collection("rides")

    let first = ridesRef.limit(to: 3)

    first.addSnapshotListener { (snapshot, err) in
        if let snapshot = snapshot {
            // Snapshot isn't nil
            if self.rides.isEmpty {
                // rides array is empty (initial data needs to be loaded in).
                let initialRides = snapshot.documents.compactMap({Ride(dictionary: $0.data())})
                self.rides.append(contentsOf: initialRides)
                self.fetchingMore = false
                DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
                    self.tableView.reloadData()
                })
                print("first rides loaded in")
            }
        } else {
            // Error
            print("Error retreiving rides: \(err.debugDescription)")
            return
        }

        // reference to lastSnapshot
        guard let lastSnapshot = snapshot!.documents.last else{
            // The collection is empty
            return
        }


        let next = ridesRef.limit(to: 4).start(afterDocument: lastSnapshot)

        next.addSnapshotListener({ (snapshot, err) in
            if let snapshot = snapshot {

                if !self.rides.isEmpty {

                    let newRides = snapshot.documents.compactMap({Ride(dictionary: $0.data())})
                    self.rides.append(contentsOf: newRides)
                    self.fetchingMore = false
                    DispatchQueue.main.asyncAfter(deadline: .now() + 7, execute: {
                        self.tableView.reloadData()
                    })

                    print("new items")
                    return
                }
            } else {
                print("Error retreiving rides: \(err.debugDescription)")
                return
            }

        })
    }
}

最佳答案

所以这是我想出的解决方案!这个解决方案很可能会多次调用firestore,从而为任何实际项目产生大量账单,但是我想您可以说它可以作为概念证明。

如果您有任何建议或正在编辑,请随时与分享!

这是所有变量的初始化方式:

var rides = [Ride]()
var lastDocumentSnapshot: DocumentSnapshot!
var fetchingMore = false

如果您有任何建议或修改,请随时分享!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offsetY = scrollView.contentOffset.y
    let contentHeight = scrollView.contentSize.height
    //print("offsetY: \(offsetY) | contHeight-scrollViewHeight: \(contentHeight-scrollView.frame.height)")
    if offsetY > contentHeight - scrollView.frame.height - 50 {
        // Bottom of the screen is reached
        if !fetchingMore {
            paginateData()
        }
    }
}

// Paginates data
func paginateData() {

    fetchingMore = true

    var query: Query!

    if rides.isEmpty {
        query = db.collection("rides").order(by: "price").limit(to: 6)
        print("First 6 rides loaded")
    } else {
        query = db.collection("rides").order(by: "price").start(afterDocument: lastDocumentSnapshot).limit(to: 4)
        print("Next 4 rides loaded")
    }

    query.getDocuments { (snapshot, err) in
        if let err = err {
            print("\(err.localizedDescription)")
        } else if snapshot!.isEmpty {
            self.fetchingMore = false
            return
        } else {
            let newRides = snapshot!.documents.compactMap({Ride(dictionary: $0.data())})
            self.rides.append(contentsOf: newRides)

            //
            DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                self.tableView.reloadData()
                self.fetchingMore = false
            })

            self.lastDocumentSnapshot = snapshot!.documents.last
        }
    }
}

关于swift - 使用Firebase Firestore分页-Swift 4,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52192062/

10-10 09:02