Заголовок UITableView заголовка Автоматическая высота не обновляется должным образом
У меня возникает проблема с автоматическими/динамическими представлениями заголовка раздела UITableView, которые содержат UILabel, который обертывает (numberOfLines = 0). Высота не вычисляется должным образом, особенно после прокрутки таблицы, и представления повторно используются. Иногда UILabel обертывается, иногда он усекается, иногда один или несколько ярлыков не видны, и иногда между ярлыками имеется дополнительное расстояние. Пользовательский вид содержит вертикальный UIStackView с тремя UILabels, один раз из которых обертывается.
Полное примерное приложение, демонстрирующее проблему, можно найти в https://github.com/outerstorm/tableviewHeaderTest.
Высота заголовка раздела задается автоматически в viewDidLoad со следующим:
tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = 30.0
а также реализовала следующую heightForHeaderInSection, чтобы попытаться заставить ее работать:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}
Я также попытался вызвать setNeedsLayout() и layoutIfNeeded() в разных точках безрезультатно. Любые предложения были бы с благодарностью.
Ниже приведен снимок экрана о поведении, наблюдаемом в приложении. Первая секция отсекается, а вторая секция слишком высокая:
![введите описание изображения здесь]()
Ответы
Ответ 1
Недавно я столкнулся с такой проблемой.
Я решил это, установив preferredMaxLayoutWidth
многострочных меток, т.е.
Перед установкой значения в меток установите preferredMaxLayoutWidth
как:
self.label1.preferredMaxLayoutWidth = self.label1.frame.size.width
self.label2.preferredMaxLayoutWidth = self.label2.frame.size.width
self.label3.preferredMaxLayoutWidth = self.label3.frame.size.width
Ответ 2
Просто добавьте функцию estimatedHeightForHeaderInSection
и верните оценочную высоту. Это решит вашу проблему. Загрузите измененный проект из здесь
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat
{
return 30;
}
Ответ 3
В общем
heightForHeaderInSection
всегда вызывается перед
viewForHeaderInSection
при использовании UITableViewAutomaticDimension высота срединного заголовка будет вычисляться только один раз, если не будет вызвано tableview.reloadData() вручную.
В коде вы каждый раз меняете текст заголовка. высота вычислялась в первый раз и не менялась автоматически.
вы можете изменить настройку func на:
func setup(someNum: Int) {
let text = String(repeating: "This is where the really long text goes so that it will wrap lines appropriately", count: someNum)
mainLabel.text = text
}
и передать индекс раздела функции
Ответ 4
Обходной способ может содержать заголовки в массиве, а затем возвращать высоту представления из оцененного метода высоты
for _ in 0 ..< data.count {
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomHeaderView") as! CustomHeaderView
view.setup()
headerViews.append(view)
}
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat
{
let view = headerViews[section] as? UIView
return (view?.frame.size.height)!
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return headerViews[section] as? UIView
}
Ответ 5
Из документации кода:
// tableView:titleForHeaderInSection: or tableView:titleForFooterInSection: if the title is not nil.
Другими словами. UITableViewAutomaticDimension
предназначен только для использования, если вы предоставляете заголовок раздела, используя titleForHeaderInSection
или titleForFooterInSection
Ответ 6
Добавить
self.label1.preferredMaxLayoutWidth = self.label1.frame.size.width
self.label1.numberoflines = 0;
self.label1.linebreakmode = NSLineBreakByWordWrapping;
в методе awakeFromNib
или же
Пожалуйста, проверьте это один раз