Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Нигде не вызывается invalidate() у PrototypeHeightStrategy #48

Open
drumih opened this issue Oct 7, 2016 · 7 comments
Labels

Comments

@drumih
Copy link

drumih commented Oct 7, 2016

Нигде не вызывается invalidate() у PrototypeHeightStrategy. Это иногда приводит к непредвиденному поведению и странному отображению ячеек при перезагрузке данных. Высоты начинают выдаваться не тем ячейкам.
Вероятно invalidate() должен вызываться в clear() у TableDirector.

@desyatov desyatov mentioned this issue Oct 7, 2016
@maxsokolov
Copy link
Owner

maxsokolov commented Oct 7, 2016

@drumih привет!
Спасибо за репортинг бага.

Используется настройка shouldUsePrototypeCellHeightCalculation?
А можно чуть подробнее про перезагрузку данных? Перезагрузка в данном случае - это загрузка новых данных из сети и создание TableRow? Или речь идет о tableView.reloadData?

Тут стоит копнуть глубже потому что кеширование высот не завязано на indexPath, и хеш для кеширования высоты считается в зависимости от ширины экрана и хеша TableRow:

let hash = row.hashValue ^ Int(tableView.bounds.size.width).hashValue

row.hashValue это ObjectIdentifier(self).hashValue у TableRow. Соответственно row.hashValue у каждого нового TableRow должен быть уникальный и перезагрузка данных не должна приводить к проблемам с высотами, несмотря на то что invalidate() нигде не вызывается.

@drumih
Copy link
Author

drumih commented Oct 7, 2016

Да, shouldUsePrototypeCellHeightCalculation = true

У нас на экране есть UIRefreshControl, на него повешена перезагрузка данных из сети, на перезагрузку данных повешен такой код:

self?.tableDirector.clear()
self?.tableDirector += tableSection
self?.tableDirector.reload()

У нас на экране 4 типа ячеек и некоторые из них повторяются, а некоторые нет.
Если много раз подряд быстро дергать refreshControl, то возникает проблема, что, например, первой ячейке выдается высота второй и второй тоже выдается высота второй или другие такие комбинации.
Есть подозрение, что хеши оказываются не уникальными (хотя это странно), но это я еще не проверял.

Приведение clear() в TableDirector к такому виду проблему решило.

public func clear() -> Self {
        heightStrategy?.invalidate()
        sections.removeAll()
        return self
    }

И еще было бы удобно писать свои реализации CellHeightCalculatable, вроде архитектура библиотеки это легко позволяет

@maxsokolov
Copy link
Owner

@drumih а в ячейках есть многострочные лейблы? У них есть preferredMaxLayoutWidth? Если нет, помогает ли

override func layoutSubviews() {
        super.layoutSubviews()

        contentView.layoutIfNeeded()
        multilineLabel.preferredMaxLayoutWidth = multilineLabel.bounds.size.width
}

?

@maxsokolov
Copy link
Owner

maxsokolov commented Oct 7, 2016

Завел задачу для своих CellHeightCalculatable #51. Это планировалось сделать.

@drumih
Copy link
Author

drumih commented Oct 7, 2016

установка preferredMaxLayoutWidth не помогает

@maxsokolov , может это как-то поможет
вот так должно быть (при первой загрузке всегда норм)
photo_2016-10-07_18-19-39

а вот так иногда становится (чем больше раз обновляешь, тем чаще возникает)
высоты могут выдаваться в абсолютно случайных комбинациях
photo_2016-10-07_18-19-34
photo_2016-10-07_18-19-45

@maxsokolov
Copy link
Owner

maxsokolov commented Oct 7, 2016

Видимо проблема все же есть где-то внутри. Раз помогает:

public func clear() -> Self {
        heightStrategy?.invalidate()
        sections.removeAll()
        return self
}

Давайте тогда сливать pr #49. Чистить кеш в любом случае нужно, сейчас это нигде не делается.

Отдельно попробую воспроизвести этот кейс и найти проблему.

@maxsokolov
Copy link
Owner

maxsokolov commented Oct 7, 2016

@drumih обновил версию в ветке swift2.2 до 1.2.1, добавил также в Cocoapods.
@desyatov спасибо!

@maxsokolov maxsokolov added the bug label Oct 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants