मैं यह पता लगाने की कोशिश कर रहा हूं कि उपयोगकर्ता स्क्रॉल कर रहा है और वह नीचे के करीब आता है ताकि मैं अपना अगला बैच डेटा लोड कर सकूं। मैंने scrollViewDidScroll(_ scrollView: UIScrollView) लागू किया है लेकिन कुछ नहीं होता है। ट्रिगर होने का एकमात्र समय तब होता है जब मैं सबसे नीचे होने के बाद स्क्रीन को ऊपर खींचता हूं। इसलिए इसे ट्रिगर करने के लिए मुझे नीचे से आगे जाने की जरूरत है।

मुझसे यहां क्या गलत हो रहा है ?

import SwiftUI

struct RequestsListView: View {
    @ObservedObject var requestsViewModel: RequestsViewModel
    
    var body: some View {
        List {
            ForEach(requestsViewModel.requests) { (request: Request) in
                if let item = request.item {
                    RequestRowView(
                        requestViewModel: RequestViewModel(request: request),
                        itemViewModel: ItemViewModel(item: item)
                    )
                    .onAppear() {
                        if let index = requestsViewModel.requests.firstIndex(where: {$0.id == request.id}), index == 0 {
                            print("load more")
                            //requestsViewModel.load()
                        }
                    }
                }
            }
        }
        .onAppear() {
            print("initialise")
            if !requestsViewModel.loaded {
                requestsViewModel.load()
            }
        }
    }
}

class RequestsViewModel: ObservableObject {
    @Published var requests = [Request]()
    @Published var error = ""
    @Published var loaded = false
    
    var firestoreService: FirestoreService = FirestoreService()
    var uid = Auth.auth().currentUser?.uid
    var lastDocumentSnapshot: DocumentSnapshot?
    var field: String
    
    let limit = 6
    
    init(field: String) {
        self.field = field
    }
    
    func load() {
        guard let uid = self.uid else { return }
        var query: Query!
        
        let itemsCollection: Query = Firestore.firestore().collection("requests").whereField(field, isEqualTo: uid)
        //everytime you need more data fetched and on database updates to your snapshot this will be triggered
        
        // ver order
        if let nextStartingSnap = self.lastDocumentSnapshot {
            query = itemsCollection.start(afterDocument: nextStartingSnap).limit(to: limit)
        } else {
            query = itemsCollection.limit(to: limit)
        }
        
        query.addSnapshotListener { (snapshot, error) in
            self.loaded = true
            
            guard let snapshot = snapshot else {
                self.error = error!.localizedDescription
                return
            }
            
            guard let lastSnapshot = snapshot.documents.last else {
                // The collection is empty.
                return
            }
            
            self.lastDocumentSnapshot = lastSnapshot
            
            snapshot.documentChanges.forEach { (documentChange) in
                
                if (documentChange.type == .added) {
                    var request = Request(document: documentChange.document)
                    self.firestoreService.fetchDocument(documentReference: request.itemReference) { (result: Result<Item, Error>) in
                        switch result {
                        case .success(let item):
                            request.item = item
                            self.requests.append(request)
                        case .failure(let error):
                            self.error = error.localizedDescription
                        }
                    }
                }
            }
        }
    }
}
1
M1X 12 जुलाई 2020, 17:02

1 उत्तर

सबसे बढ़िया उत्तर

मैंने यह पता लगाने के माध्यम से किया कि क्या प्रदर्शित वस्तु सूची में अंतिम तत्व है, फिर fetchMore फ़ंक्शन को कॉल करके

    //EmployeeViewModel
class EmployeeViewModel: ObservableObject {
    @Published var employees : [Employee] = []
    
    func initialize() {
        self.employees = [Employee(name: "A", id: "100"),
        Employee(name: "B", id: "101"),
        Employee(name: "C", id: "102"),
        Employee(name: "D", id: "103"),
        Employee(name: "E", id: "104"),
        Employee(name: "F", id: "105"),
        Employee(name: "G", id: "106"),
        Employee(name: "H", id: "107"),
        Employee(name: "I", id: "108"),
        Employee(name: "J", id: "109"),
        Employee(name: "K", id: "110"),
        Employee(name: "L", id: "112"),
        Employee(name: "M", id: "113"),
        Employee(name: "N", id: "114"),
        Employee(name: "O", id: "115"),
        Employee(name: "P", id: "116"),
        Employee(name: "Q", id: "117"),
        Employee(name: "R", id: "118"),
        Employee(name: "S", id: "119"),
        Employee(name: "T", id: "120"),
        Employee(name: "U", id: "121"),
        Employee(name: "V", id: "122"),
        Employee(name: "W", id: "123")]
    }
    
    
    //fetch more employees inside viewmodel
    func fetchMoreEmployees(employee: Employee) {
        if let index = self.employees.firstIndex(where: {$0.id == employee.id}) {
            if index == self.employees.count - 1 {
                print("Item: \(employee.name) - Reached bottom of list ")
            } else if index == 0 {
                print("Item: \(employee.name) - Reached top of list")
            }
        }
    }
}

struct EmployeeView: View {
    @ObservedObject var vm = EmployeeViewModel()

    var body: some View {
        NavigationView {
            List {
                ForEach(self.vm.employees) { employee in
                    EmployeeCellView(vm: self.vm, employee: employee)
                }.listRowBackground(Color.white)
            }.onAppear(perform: initialize)
             .navigationBarTitle("Users", displayMode: .inline)
       }
    }
    
    func initialize() {
        self.vm.initialize()
    }
}

struct EmployeeCellView: View {
    @ObservedObject var vm: EmployeeViewModel
    let employee: Employee
    
    var body: some View {
        Text("\(employee.name)").onAppear(perform: fetchMore)
    }
    
    func fetchMore() {
        self.vm.fetchMoreEmployees(employee: self.employee)
    }
}

इस fetchMoreEmployees(employee: Employee) फ़ंक्शन को अपने ViewModel के अंदर जोड़ें और इस फ़ंक्शन को ऊपर दिखाए गए अपने सेल के .onAppear() में कॉल करें।

1
Sona 14 जुलाई 2020, 09:28