SwiftUI asyn c Выборка данных - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь изучить SwiftUI и создаю поисковое приложение mov ie с API-интерфейсом базы данных mov ie

Я хотел бы получить новые данные, как только прокрутка переместится в конец списка. Я нашел возможное решение для SO, используя ForEach внутри Списка и проверяя, когда список достигает последнего элемента, а затем выполняя вызов onAppear ().

В SwiftUI, где находятся события управления, т.е. scrollViewDidScroll определить нижнюю часть списка данных

Как я могу загрузить новые страницы из поиска после загрузки первой страницы?

Вы можете найти проект здесь, он был слишком велик для публикации https://github.com/aspnet82/MovieSearch

SearchMovieManager -> Выполнить вызов выборки, я использовал Dispatch.main.asyn c

Вот что приложение должно делать

  1. Извлечение данных из API и отображение первой страницы -> РАБОТА *
  2. Когда прокрутка списка до последнего элемента делает еще один запрос на выборку на следующей странице для загрузки дополнительных данных -> Это не работает, это работает только для второй страницы запроса. Он всегда отображает одни и те же данные после второго вызова извлечения.

Мне кажется, что проблема в GCD, но я не знаю, как поставить вещи в очередь, чтобы она работала автоматически

ОБНОВЛЕНИЕ: Обходной путь, который я нашел:

List(searchMovieManager.allMovies) { movie in
     Text(movie.title)
}
Text("load more").onTapGesture {
     fetchNextPage(obs: self.searchMovieManager, page: self.searchMovieManager.pageTofetch)
 }

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

Спасибо за помощь:)

1 Ответ

0 голосов
/ 06 марта 2020

Попробуйте следующее: он использует настройки привязки и простую модель, которая имитирует асинхронную операцию c, чтобы добавить некоторые записи в ScrollView (или List)

import SwiftUI

struct PositionData: Identifiable {
    let id: Int
    let center: Anchor<CGPoint>
}

struct Positions: PreferenceKey {
    static var defaultValue: [PositionData] = []
    static func reduce(value: inout [PositionData], nextValue: () -> [PositionData]) {
        value.append(contentsOf: nextValue())
    }
}

struct Data: Identifiable {
    let id: Int
}

class Model: ObservableObject {
    var _flag = false
    var flag: Bool {
        get {
            _flag
        }
        set(newValue) {
            if newValue == true {
                _flag = newValue

                DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                    self._flag = false
                    self.rows += 20
                    print("done")
                }
            }
        }
    }
    @Published var rows = 20
}
struct ContentView: View {
    @ObservedObject var model = Model()
    var body: some View {
        List {
            ForEach(0 ..< model.rows, id:\.self) { i in
                Text("row \(i)").font(.largeTitle).tag(i)
            }
            Rectangle().tag(model.rows).frame(height: 0).anchorPreference(key: Positions.self, value: .center) { (anchor) in
                [PositionData(id: self.model.rows, center: anchor)]
            }.id(model.rows)
        }
        .backgroundPreferenceValue(Positions.self) { (preferences) in
            GeometryReader { proxy in
                Rectangle().frame(width: 0, height: 0).position(self.getPosition(proxy: proxy, tag: self.model.rows, preferences: preferences))
            }
        }
    }
    func getPosition(proxy: GeometryProxy, tag: Int, preferences: [PositionData])->CGPoint {
        let p = preferences.filter({ (p) -> Bool in
            p.id == tag
            })
        if p.isEmpty { return .zero }
        if proxy.size.height - proxy[p[0].center].y > 0 && model.flag == false {
            self.model.flag.toggle()
            print("fetch")
        }
        return .zero
    }
}



struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

, и вот как это выглядит ...

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...