Differ icon indicating copy to clipboard operation
Differ copied to clipboard

Move row in moving section failed in TableView

Open jcislinsky opened this issue 7 years ago • 4 comments

Hi, I just reached to problem with moving rows inside of section that is moved in the same update. Example app (NestedTableViewController) have this issue. I updated items in https://github.com/EtneteraMobile/Differ/tree/test-move to highlight invalid behaviour.

This is result of update, where section are switched and rows inside are switched too. Expected result: Second – 2, 1; First – 2, 1 Invalid result: Second – 2, 1; First – 1, 2

It seems to be bug in UITableView that doesn't perform move in section that is moving. simulator screen shot - iphone x - 2018-04-18 at 10 56 58

jcislinsky avatar Apr 18 '18 10:04 jcislinsky

Thanks for the report, and for the reproduction!

tonyarnold avatar Apr 19 '18 09:04 tonyarnold

Huh, yeah, this is a really odd one. How did you figure it was a UITableView bug?

tonyarnold avatar Apr 21 '18 00:04 tonyarnold

It's my tip.

I wrote test that compares content in cells (extracted from subviews of tableView) with model.

private extension UITableView {
    var testDescription: String {
        return subviews
            .sorted {
                $0.frame.origin.y < $1.frame.origin.y
            }.reduce("") { accum, current in
                let appendix: String
                if let text = (current as? UITableViewCell)?.textLabel?.text {
                    appendix = "\(text);"
                } else if let headerFooterText = (current as? UITableViewHeaderFooterView)?.textLabel?.text {
                    appendix = "\(headerFooterText);"
                } else if let text = (current as? UILabel)?.text {
                    appendix = "\(text);"
                } else if current is UIImageView {
                    appendix = ""
                } else {
                    print("Unknown \(current)")
                    fatalError()
                }
                return accum + appendix
        }
    }
}

but it succeeded 🤦🏻‍♂️.

It's weird that unit test succeeded but real use on device failed.

It's possible to fix this case with two update blocks. First update without rows move in moving section and then move rows. I have working version of this.

There is one more problem with reload row in moving section as I know now. Maybe we can try insert and delete in moving section.

jcislinsky avatar Apr 24 '18 05:04 jcislinsky

Hi @jcislinsky, I'm currently trying to find a solution to this problem since even UITableViewDiffableDataSource on iOS 13 behaves incorrectly.

You mentioned applying the updates through two update blocks. While this works for this simple case, I don't believe we can make it work for every possible scenario because the intermediate state needs to be valid for UITableView — at least concerning the number of sections and rows therein.

But maybe I am misunderstanding what you were trying to do. Could you please elaborate on your idea a bit?

jenox avatar Dec 29 '19 19:12 jenox