SwiftUI нумерация страниц для объекта List - PullRequest
1 голос
/ 23 января 2020

Я реализовал список с панелью поиска в SwiftUI. Теперь я хочу реализовать пейджинг для этого списка. Когда пользователь прокручивает до конца списка, должны быть загружены новые элементы. Моя проблема в том, как я могу определить, что пользователь прокрутил до конца? Когда это происходит, я хочу загрузить новые элементы, добавить их и показать их пользователю.

Мой код выглядит следующим образом:

import Foundation
import SwiftUI

struct MyList: View {
    @EnvironmentObject var webService: GetRequestsWebService

    @ObservedObject var viewModelMyList: MyListViewModel

    @State private var query = ""

    var body: some View {

        let binding = Binding<String>(
            get: { self.query },
            set: { self.query = $0; self.textFieldChanged($0) }
        )

        return NavigationView {
            // how to detect here when end of the list is reached by scrolling?
            List {
                // searchbar here inside the list element
                TextField("Search...", text: binding) {
                    self.fetchResults()
                }

                ForEach(viewModelMyList.items, id: \.id) { item in
                    MyRow(itemToProcess: item)
                }
            } 
            .navigationBarTitle("Title")
        }.onAppear(perform: fetchResults)

    }

    private func textFieldChanged(_ text: String) {        
        text.isEmpty ? viewModelMyList.fetchResultsThrottelt(for: nil) : viewModelMyList.fetchResultsThrottelt(for: text)
    }

    private func fetchResults() {
        query.isEmpty ? viewModelMyList.fetchResults(for: nil) : viewModelMyList.fetchResults(for: query)
    }
}

Также этот случай немного особенный, потому что список содержит панель поиска. Буду благодарен за любой совет, потому что с этим:).

Ответы [ 2 ]

3 голосов
/ 23 января 2020

Добавьте .onAppear() к MyRow и вызовите viewModel с элементом, который только что появился. Затем вы можете проверить, равен ли он последнему элементу в списке или его n элементов удалены от конца списка, и запустить пагинацию.

2 голосов
/ 24 января 2020

Поскольку у вас уже есть List с искусственной строкой для строки поиска, вы можете просто добавить другой список в список, который будет вызывать другой выбор, когда он появится на экране (используя onAppear(), как предложено Джо sh). Делая это, вам не нужно делать никаких «сложных» вычислений, чтобы узнать, является ли строка последней строкой ... искусственная строка всегда последней!

Я уже использовал это в одном из своих проектов и я никогда не видел этот элемент на экране, так как загрузка была запущена так быстро, прежде чем она появилась на экране. (Вы наверняка можете использовать прозрачный / невидимый элемент, или, возможно, даже использовать спиннер; -))

            List {
                TextField("Search...", text: binding) { /* ... */ }

                ForEach(viewModelMyList.items, id: \.id) { item in
                    // ...
                }

                if self.viewModelMyList.hasMoreRows {
                    Text("Fetching more...")
                        .onAppear(perform: {
                            self.viewModelMyList.fetchMore()
                        })
                }
...