之前我们做的版本只有一个列表视图,并没有办法实现滚动翻页,今天我们在原来的列表视图基础上,增加一个无限下拉翻页的功能。
- 修改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,为了让下一次请求可以获取新一页数据。
- 修改ResourceList视图文件
将viewModel变量的修饰符由@ObservedObject改为@StateObject。主要的区别是@ObservedObject每次进入视图都会新创建,而@StateObject只会被创建一次。
- @ObservedObject var viewModel = ResourceViewModel()
+ @StateObject var viewModel = ResourceViewModel()
在视图VStack结尾增加onAppear生命周期函数,即刚刚显示视图时,便调用viewModel.loadMoreContentIfNeeded()方法来加载第一页数据。
VStack {
....
}.onAppear {
viewModel.loadMoreContentIfNeeded(currentItem: resource)
}
这样便完成了无限加载瀑布流
- 额外记录 - 根据是否是暗色模式加载不同图片
首先 设置colorSchema变量
@Environment(\.colorScheme) var colorScheme
其次 在用到的地方进行判断
colorScheme == .light ?
Image("tv1").resizable().frame(width: 18, height: 18):
Image("tv").resizable().frame(width: 18, height: 18)
网友评论