Подтвердить что ты не робот

Заголовок 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() в разных точках безрезультатно. Любые предложения были бы с благодарностью.

Ниже приведен снимок экрана о поведении, наблюдаемом в приложении. Первая секция отсекается, а вторая секция слишком высокая:

введите описание изображения здесь

4b9b3361

Ответ 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