Swift 4中如何按列值对UITableView进行排序?
Hey Augusto, I spot the exact issue with your sorting code right away—let's break it down and get it working!
The Root Cause
In Swift, the sorted(by:) method is non-mutating: it doesn't modify the original array you call it on. Instead, it creates and returns a brand new array with elements sorted to your specifications.
In your current code, you're running self.ticker.sorted(by: { $0.change > $1.change }) but never assigning that sorted new array back to self.ticker. Your original array stays unchanged, so the table view has no reason to look different after reloading data.
The Simple Fix
All you need to do is assign the sorted result back to your ticker variable. Here's the corrected tap handler:
@objc func tapChangeFunction(sender: UITapGestureRecognizer) { // Assign the sorted array back to the original variable self.ticker = self.ticker.sorted(by: { $0.change > $1.change }) DispatchQueue.main.async { self.table.reloadData() } }
Bonus: Add Toggleable Sort Direction
If you want users to switch between ascending and descending order when tapping the header multiple times, add a small state variable to track the current sort direction:
// Add this property to your view controller private var isChangeSortDescending = true @objc func tapChangeFunction(sender: UITapGestureRecognizer) { // Sort based on the current direction self.ticker = self.ticker.sorted(by: { if isChangeSortDescending { return $0.change > $1.change } else { return $0.change < $1.change } }) // Flip the direction for the next tap isChangeSortDescending.toggle() DispatchQueue.main.async { self.table.reloadData() } }
Quick Sanity Check
Double-check that your table view's data source methods are properly using the ticker array:
tableView(_:numberOfRowsInSection:)returnsticker.counttableView(_:cellForRowAt:)pulls data fromticker[indexPath.row]
That's all—your list should now sort correctly every time you tap the header!
内容的提问来源于stack exchange,提问作者Augusto

