gpt4 book ai didi

list - SwiftUI 异步数据获取

转载 作者:行者123 更新时间:2023-12-04 10:27:39 25 4
gpt4 key购买 nike

我正在尝试学习 SwiftUI 并使用电影数据库 API 创建电影搜索应用程序

一旦滚动到达列表末尾,我想获取新数据。我在列表中使用 ForEach 找到了一个可能的解决方案,并检查列表何时到达最后一个项目,然后执行 onAppear() 调用。

In SwiftUI, where are the control events, i.e. scrollViewDidScroll to detect the bottom of list data

加载第一页后,如何从搜索中加载新页面?

你可以在这里找到这个项目,太大了,无法发布
https://github.com/aspnet82/MovieSearch

SearchMovieManager -> 进行 fetch 调用,我使用了 Dispatch.main.async

这里应用程序应该做什么

  • 从 API 中获取数据并显示第一页 -> WORKING
  • 当列表滚动到最后一个项目在下一页发出另一个获取请求以加载更多数据时 -> 这不起作用,它仅适用于请求的第二页。它总是在第二次 fetch 调用后显示相同的数据。

  • 我认为问题出在 GCD 中,但我不知道如何排队以使其自动工作

    更新:我发现的解决方法:
    List(searchMovieManager.allMovies) { movie in
    Text(movie.title)
    }
    Text("load more").onTapGesture {
    fetchNextPage(obs: self.searchMovieManager, page: self.searchMovieManager.pageTofetch)
    }

    我认为作为解决方案可能还可以,一旦我点击按钮它就会添加新页面,并且在控制数据下载方面也可以很好吗?

    谢谢您的帮助 :)

    最佳答案

    尝试下一个,它使用 anchor 首选项和模拟异步操作的简单模型将一些记录添加到 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

    关于list - SwiftUI 异步数据获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60563668/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com