TableView滑出视图时单元格右移问题求助
Hey there! Let’s figure out why your TableView cells keep shifting right once they scroll out of view. The most likely culprit here is cell reuse combined with unreset constraint values—let’s break this down.
The Root Cause
When TableView cells scroll off-screen, they get recycled into the reuse pool. Right now, in your cellForRowAt method, you’re updating the spacingViewWidthConstraint.constant by multiplying its current value by the depth:
cell.spacingViewWidthConstraint.constant = cell.spacingViewWidthConstraint.constant * CGFloat(self.depthDictionary[structure.id]!)
This means every time a cell is reused, you’re stacking on top of the previous constraint value instead of starting fresh. For example, if a cell was originally set to 20pt for depth 1, when it’s reused for a depth 2 item, you’re making it 202=40pt. Then if it’s reused again for depth 1, you get 401=40pt instead of resetting to the original base value multiplied by depth. That’s why the shift gets worse over time!
Fix 1: Reset to a Base Value First
First, you need to store the original, unmodified width of your spacing view so you can calculate the correct constraint each time. Here’s how to do it:
- In your
StructureNavigationCellclass, add a property to hold the initial spacing width:
class StructureNavigationCell: UITableViewCell { @IBOutlet weak var spacingViewWidthConstraint: NSLayoutConstraint! var originalSpacingWidth: CGFloat = 0 override func awakeFromNib() { super.awakeFromNib() // Save the original constraint value when the cell is initialized originalSpacingWidth = spacingViewWidthConstraint.constant } }
- Update your
cellForRowAtmethod to use this original value instead of the current constraint value:
let cell = tableView.dequeueReusableCell(withIdentifier: "StructureNavigationCell", for: IndexPath(row: row, section: 0)) as! StructureNavigationCell cell.structureLabel.text = structure.name // Use the original base value multiplied by depth, not the current constraint value if let depth = self.depthDictionary[structure.id] { cell.spacingViewWidthConstraint.constant = cell.originalSpacingWidth * CGFloat(depth) } return cell
Fix 2: Reset Constraints in prepareForReuse
As an extra safeguard, override the prepareForReuse method in your cell class to reset the constraint back to its original value before it’s reused:
override func prepareForReuse() { super.prepareForReuse() spacingViewWidthConstraint.constant = originalSpacingWidth // Also reset any other reusable UI elements if needed, like labels structureLabel.text = nil }
Bonus: Double-Check Your Data Logic
While you’re at it, that structure sorting loop you mentioned is indeed inefficient for large datasets. A better approach would be to perform a recursive traversal of your structure tree to build the sorted array in one pass, instead of looping until all items are inserted. But that’s a separate refactor—focus on the constraint issue first to fix the scrolling shift.
Let me know if this resolves the problem!
内容的提问来源于stack exchange,提问作者user11733397

