SwiftReorder icon indicating copy to clipboard operation
SwiftReorder copied to clipboard

Reordering dynamically sized cells causes content to jump around significantly

Open adamshin opened this issue 8 years ago • 7 comments

This occurs when the content size is larger than the table view bounds. Probably an issue with cell height calculations.

adamshin avatar Sep 14 '16 15:09 adamshin

Great one @adamshin. I think the issue is the cells move the movement of the cells then trigger another move which causes a loop. I believe similar logic to whats here might fix this up although I could be wrong. https://github.com/Raizlabs/LXReorderableCollectionViewFlowLayout/blob/master/LXReorderableCollectionViewFlowLayout/LXReorderableCollectionViewFlowLayout.m#L157

ay8s avatar Sep 14 '16 18:09 ay8s

Thanks for the tip, I'll take a look at that.

adamshin avatar Sep 14 '16 20:09 adamshin

@ay8s Spent some time debugging this today -- unfortunately, it appears to be a UIKit issue. 😞 Calling insertRows(at:with:) or deleteRows(at:with:) on a table view with dynamically-sized cells causes the content offset to shift around unpredictably. Seems like it's related to the estimated row height you give.

I wasn't able to come up with a satisfactory solution, so I'm going to table this for now. In the meantime, a workaround would be to calculate cell heights manually (the pre-iOS 8 way).

adamshin avatar Sep 15 '16 05:09 adamshin

just do this in viewcontroller to fix this jumping:

  1. var cellHeights = NSMutableDictionary()

  2. func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
     if let height = cellHeights.object(forKey: indexPath) {
         return height as! CGFloat
     }
    
     return UITableViewAutomaticDimension
    

    }

  3. func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
     cellHeights.setObject(cell.frame.size.height, forKey: indexPath as NSCopying)
    

    }

This fixed the issue on my side.

lkuraer avatar Jan 16 '18 12:01 lkuraer

Is there a way to implement these changes within the source itself so I don't have to add all this to each of my tableViews?

cliftonlabrum avatar Jul 26 '18 04:07 cliftonlabrum

I'm using extension for UITableView - https://github.com/APUtils/APExtensions/blob/master/APExtensions/Classes/Core/_Extensions/UITableView%2BUtils.swift#L82

Then it's just one line of code: tableView.handleEstimatedSizeAutomatically = true

anton-plebanovich avatar Jan 12 '19 11:01 anton-plebanovich

Fixed in https://github.com/adamshin/SwiftReorder/pull/67

anton-plebanovich avatar Jan 18 '20 14:01 anton-plebanovich