Swift实现UITableView分页滚动:每页5条,滚动切换页码
Hey there! Let's fix your code to meet that page-switching scrolling requirement. I'll break down what's missing and how to adjust it step by step.
First, let's go over the gaps in your current code:
- When you scroll to the bottom, you increment
currentPagebut don't actually fetch the new page's data (you just reload the table with existing items). - There's no logic to detect scrolling to the top to switch to the previous page.
- You're appending new items to the array every time, which would accumulate all pages instead of showing only the current page's 5 items.
- No loading state to prevent duplicate requests if the user scrolls repeatedly before the data loads.
Here's the modified code with all the fixes:
First, add a loading flag to avoid concurrent requests:
var currentPage: Int = 1 var listLimit: Int = 5 var isLoading = false // Add this to prevent duplicate API calls
Then update your updatePropertyListWithDistrict function to handle loading state, clear the array for page switching, and safely handle the response:
func updatePropertyListWithDistrict(district: String) { guard !isLoading else { return } // Don't proceed if already loading data isLoading = true MBProgressHUD.showAdded(to: self.view, animated: true) // Show loading indicator while fetching PSPWCFService.sharedClient.PropertyList(district: district, PageNumber: currentPage, PageSize: listLimit) { (json, error) in // Ensure we always hide the HUD and reset loading state, even if there's an error defer { MBProgressHUD.hide(for: self.view, animated: true) self.isLoading = false } if let error = error { print(error.localizedDescription) // Optional: Show an error alert to the user here for better UX return } let jsonArray = json?.array ?? [] // Safely unwrap to avoid crashes if JSON is invalid self.properties.removeAll() // Clear existing items to show only current page's 5 items for object in jsonArray { let newProperty = Property(json: object) self.properties.append(newProperty) } self.tableView.reloadData() if self.properties.isEmpty { let alertController = UIAlertController(title: "Alert", message: "No listings available in the area.", preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "Dismiss", style: .default)) self.present(alertController, animated: true) } } }
Next, update the scrollViewDidEndDragging method to detect both bottom (next page) and top (previous page) scrolls:
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { guard scrollView == tableView, !isLoading else { return } // Only act on the table view and if not loading // Check if scrolled to the bottom to load next page let isAtBottom = (scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height if isAtBottom { currentPage += 1 updatePropertyListWithDistrict(district: "ABC") // Optional: Scroll to the top of the new page after loading for smoother transition // tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true) return } // Check if scrolled to the top to load previous page (only if not on the first page) let isAtTop = scrollView.contentOffset.y <= 0 if isAtTop && currentPage > 1 { currentPage -= 1 updatePropertyListWithDistrict(district: "ABC") // Optional: Scroll to the bottom of the previous page after loading // tableView.scrollToRow(at: IndexPath(row: properties.count - 1, section: 0), at: .bottom, animated: true) } }
Key changes explained:
- Loading State: The
isLoadingflag prevents overlapping API calls if the user scrolls quickly before the previous request finishes. - Page Switching: We clear the
propertiesarray before adding new items so each page only shows 5 items (matches your "switch to next/previous page" requirement). If you want infinite scroll (accumulate all loaded items instead of switching), just remove theself.properties.removeAll()line. - Top Scroll Detection: Added logic to trigger the previous page when the user scrolls to the top (as long as we're not on page 1).
- Safe Handling: Replaced force unwrapping of
jsonArraywith a safe default to avoid crashes, and useddeferto ensure loading state and HUD are always reset. - Loading Indicator: Added showing the HUD when the request starts (your original code only hid it).
内容的提问来源于stack exchange,提问作者William Loke
相关产品推荐
相关产品推荐

