美文网首页SwiftUI使用SwiftUI开发一个APP
使用SwiftUI开发一个APP - 无限加载瀑布流

使用SwiftUI开发一个APP - 无限加载瀑布流

作者: LazyGunner | 来源:发表于2021-08-26 16:48 被阅读0次

    之前我们做的版本只有一个列表视图,并没有办法实现滚动翻页,今天我们在原来的列表视图基础上,增加一个无限下拉翻页的功能。

    1. 修改ResourceViewModel
      首先我们要增加一个变量用来保存当前页数
    private var currentPage = 1
    

    增加一个方法,当需要加载更多内容的时候调用

        func loadMoreContentIfNeeded(currentItem item: Resource?) {
          guard let item = item else {
            getResourceList()
            return
          }
    
          let thresholdIndex = resourceList.index(resourceList.endIndex, offsetBy: -5)
          if resourceList.firstIndex(where: { $0.id == item.id }) == thresholdIndex {
            getResourceList()
          }
        }
    

    这段代码主要作用是:
    当第一次加载页面时,调用一次getResourceList()获取第一页数据
    当滑动到的对象是resourceList中倒数第5个时,再次调用getResourceList()获取新一页的数据。

    接下来我们要修改我们的获取资源列表的接口getResourceList()

    -        let queryItems = [URLQueryItem(name: "page", value: "1")]
    +        let queryItems = [URLQueryItem(name: "page", value: String(currentPage))]
    将分页变量作为URL参数传给请求。
                 .sink(receiveCompletion: { _ in }, // 6
                       receiveValue: {
    -                    self.resourceList = $0.data // 7
    +                    if ($0.data.count > 0) {
    +                        self.resourceList += $0.data // 7
    +                        self.currentPage += 1
    +                    }
                 })
    

    在返回数据的处理函数中,增加如果当前页面返回数据数量 >0 则当前页码+1,为了让下一次请求可以获取新一页数据。

    1. 修改ResourceList视图文件
      将viewModel变量的修饰符由@ObservedObject改为@StateObject。主要的区别是@ObservedObject每次进入视图都会新创建,而@StateObject只会被创建一次。
    -    @ObservedObject var viewModel = ResourceViewModel()
    +    @StateObject var viewModel = ResourceViewModel()
    在视图VStack结尾增加onAppear生命周期函数,即刚刚显示视图时,便调用viewModel.loadMoreContentIfNeeded()方法来加载第一页数据。
      VStack {
        ....
      }.onAppear {
        viewModel.loadMoreContentIfNeeded(currentItem: resource)
      }
    

    这样便完成了无限加载瀑布流

    1. 额外记录 - 根据是否是暗色模式加载不同图片
      首先 设置colorSchema变量
    @Environment(\.colorScheme) var colorScheme
    

    其次 在用到的地方进行判断

    colorScheme == .light ?
        Image("tv1").resizable().frame(width: 18, height: 18):
        Image("tv").resizable().frame(width: 18, height: 18)
    

    相关文章

      网友评论

        本文标题:使用SwiftUI开发一个APP - 无限加载瀑布流

        本文链接:https://www.haomeiwen.com/subject/dbeuiltx.html