分页代码是在启动时触发的,而不是当用户到达页面底部时触发的



我正在尝试为表视图实现一个无限滚动/分页功能。我使用scrollViewDidScroll来测量用户何时到达页面底部,然后触发一个函数来获取下一批数据。然而,我认为测量是关闭的,因为我的fetchMoreEvents功能是在应用程序启动时触发的。

这是分页代码(scrollViewDidScrollfetchMoreEvents(:

func fetchMoreEvents() {
fetchingMore = true
var page = 1
page += 1
let seatGeekApiUrl = URL(string: "https://api.seatgeek.com/2/events?venue.state=NY&page=(page)&client_id=MTM5OTE0OTd8MTU0MjU2NTQ4MC4z")!
fetchData(url: seatGeekApiUrl) { (result: FetchResult<Welcome>) -> (Void) in
switch result {
case .success(let object): self.eventData.append(contentsOf: object.events)
print("neventData: nn(self.eventData)")
case .failure(let error):
print("nError decoding JSON: nn(error)")
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
print("nFetching next batch of events: (Page (page))n")
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.height {
if !fetchingMore {
fetchMoreEvents()
}
}
}

一旦触发了fetchMoreEvents,我就让它将下一页的结果附加到我的eventData数组中,并重新加载表视图。我的print语句确认它获取了数据的第2页,但正如我所说,这会立即发生,而不是当我向下滚动页面时。此外,它再也不会被触发。

这是scrollViewDidScroll中的测量值有问题,还是我在其他地方出错了

这些是表视图方法,如果它们在这里适用的话:

override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return eventData.count
} else if section == 1 && fetchingMore {
return 1
}
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "eventsCell", for: indexPath) as! EventsTableViewCell
let event = eventData[indexPath.row]
// Labels
cell.eventNameLabel.text = event.title
cell.eventVenueLabel.text = event.venue.nameV2
cell.eventAddressLabel.text = event.venue.address
cell.eventTimeLabel.text = dateFormatter.string(from: event.dateTimeLocal)
// Image
if let urlString = event.performers[0].image, let imageURL = URL(string: urlString) {
ImageService.getImage(url: imageURL) { (image) in
cell.eventImageView.image = image
}
}
else {
cell.eventImageView.image = UIImage(named: "noImageFound")
}
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "loadingCell", for: indexPath) as! LoadingCell
cell.spinner.startAnimating()
return cell
}
}

将布尔声明为属性

var isAllRowSeeked: Bool = false

将此逻辑放入scrollViewDidScroll

let  height = scrollView.frame.size.height
let contentYoffset = scrollView.contentOffset.y
let distanceFromBottom = scrollView.contentSize.height - contentYoffset
if distanceFromBottom < height,
self.isAllRowSeeked == true {
// you've reached the end, you are now ready to load more data
self.isAllRowSeeked = false
}

现在处于cellForRowAtIndexPath

if  fetchingMore == true,
isLastSectionRow(indexPath: indexPath) {// it's the last row of this section
state.isAllRowSeeked = true
return paginatorUI?.getPaginatedLoadMoreCell()
} else {
return nil
}

添加以下方法

public func isLastSectionRow(indexPath: IndexPath) -> Bool {
let lastSection = tableview.dataSource?.numberOfSections?(in: tableview)
?? 1
let lastRow = tableview.dataSource?.tableView(tableview,
numberOfRowsInSection: indexPath.section)
?? 0
return lastSection == (indexPath.section+1) && lastRow == (indexPath.row+1)
}

实际上,这个逻辑是从我的一个pod中借来的,你可以使用它。此分页的完整代码可以在这里找到

最新更新