首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI异步数据获取

SwiftUI异步数据获取
EN

Stack Overflow用户
提问于 2020-03-06 12:01:09
回答 1查看 2.9K关注 0票数 2

我正在努力学习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 ->进行了提取调用,我使用了Dispatch.main.async

在这里,应用程序应该做什么?

  1. 从API中获取数据并显示第一页-> WORKING
  2. ,当列表滚动到最后一项时,在下一页上进行另一次获取请求以加载更多的数据-> --这不起作用,它只对请求的第二页起作用。它总是在第二次获取调用之后显示相同的数据。

我认为问题在GCD中,但我不知道如何排队使它自动工作。

更新:我找到了一个解决办法:

代码语言:javascript
复制
List(searchMovieManager.allMovies) { movie in
     Text(movie.title)
}
Text("load more").onTapGesture {
     fetchNextPage(obs: self.searchMovieManager, page: self.searchMovieManager.pageTofetch)
 }

我认为,作为解决方案,它可以增加新的页面,一旦我点击按钮,也可以控制数据下载可能?

谢谢你的帮助:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-06 18:47:15

接下来,它使用锚首选项和模拟异步操作的简单模型向ScrollView (或List)添加一些记录。

代码语言:javascript
复制
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()
    }
}

这就是它的样子..。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60563668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档