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

Проблема динамической высоты для ячеек UITableView (Swift)

Динамический текст переменной длины вставляется в метки ячейки таблицы. Для того, чтобы высоты ячеек таблицы видны динамически, я реализовал в viewDidLoad():

self.tableView.estimatedRowHeight = 88.0
self.tableView.rowHeight = UITableViewAutomaticDimension

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

Я попробовал просто перезагрузить данные (как было предложено во многих других ресурсах):

self.tableView.reloadData()

как в viewDidAppear(), так и viewWillAppear(), и это было бесполезно. Я потерял.. кто-нибудь знает, как иметь xcode визуализировать динамическую высоту для ячеек, загруженных изначально на экран?

Пожалуйста, дайте мне знать, если есть лучший альтернативный метод.

4b9b3361

Ответ 1

Попробуй это:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

РЕДАКТИРОВАТЬ

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Swift 4

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Swift 4.2

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableView.automaticDimension
}

Определите выше оба метода.
Это решает проблему.

PS: для этого необходимы ограничения сверху и снизу.

Вот пример

Ответ 2

Используйте это:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300

и не использовать: heightForRowAtIndexPath функция делегирования

Кроме того, в доске объявлений не указывается высота метки, содержащей большой объем данных. Дайте ему top, bottom, leading, trailing ограничения.

Ответ 3

SWIFT 3

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160

И!!! В storyBoard: вам нужно установить TOP и BOTTOM ограничения для вашей метки. Больше ничего.

Ответ 4

Эта странная ошибка была решена с помощью параметров Interface Builder, поскольку другие ответы не устранили проблему.

Все, что я сделал, это сделать размер метки по умолчанию более крупным, чем потенциально может быть содержимое, и отразить его в высоте estimatedRowHeight. Раньше я устанавливал высоту строки по умолчанию в Interface Builder 88px и отражал ее так же в моем контроллере viewDidLoad():

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 88.0

Но это не сработало. Итак, я понял, что контент никогда не станет больше, чем, может быть, 100px, поэтому я установил высоту ячейки по умолчанию 108px (больше, чем потенциал содержимое) и отразили его так же в контроллере viewDidLoad():

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 108.0

Это фактически позволило коду уменьшить исходные метки до нужного размера. Другими словами, он никогда не расширялся до большего размера, но всегда мог сжиматься... Кроме того, в viewWillAppear() не требуется никаких дополнительных self.tableView.reloadData().

Я знаю, что это не распространяется на сильно изменяемые размеры контента, но это сработало в моей ситуации, когда содержание имело максимально возможное количество символов.

Не уверен, что это ошибка в Swift или Interface Builder, но она работает как шарм. Попробуйте!

Ответ 5

Установите автоматический размер для высоты строки и предполагаемой высоты строки и выполните следующие шаги:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

Например: если у вас есть метка в UITableviewCell, то

  • Установить количество строк = 0 (& режим разрыва строки = обрезать хвост)
  • Установите все ограничения (сверху, снизу, справа налево) относительно его контейнера superview/cell.
  • Необязательно: Установите минимальную высоту для метки, если вы хотите, чтобы минимальная вертикальная область была покрыта меткой, даже если данных нет.

Вот образец метки с динамическими ограничениями по высоте.

enter image description here

Ответ 6

Динамическая ячейка размера UITableView требовала 2 вещи

  • Установка правильного ограничения вашего представления внутри ячейки представления таблицы (в основном это включает в себя предоставление правильного верхнего, нижнего и триального ограничений)
  • Вызов этих свойств TableView в viewDidLoad()

     tableView.rowHeight = UITableViewAutomaticDimension
    
     tableView.estimatedRowHeight = 140
    

Это - замечательное учебное пособие по самостоятельной калибровке (ячейки с динамическим табличным представлением), написанное в быстрой версии.

Ответ 7

Для Swift 3 вы можете использовать следующее:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Ответ 8

Try

override func viewWillAppear(animated: Bool) {
    self.tableView.layoutSubviews()
}

У меня была такая же проблема, и она работает для меня.

Ответ 9

Чтобы сделать автоматизацию работы UITableViewCell, убедитесь, что вы делаете эти изменения:

  • В раскадровке ваш UITableView должен содержать только ячейки динамического прототипа (он не должен использовать статические ячейки), в противном случае авторезизация не будет работать.
  • В раскадровке ваш UITableViewCell's UILabel сконфигурировал для всех 4 ограничений, которые находятся сверху, снизу, ведущие и конечные ограничения.
  • В раскадровке ваш UITableViewCell's Количество строк UILabel должно быть 0
  • В вашем UIViewController Функция viewDidLoad, установленная ниже Свойства UITableView:

    self.tableView.estimatedRowHeight = <minimum cell height> 
    self.tableView.rowHeight = UITableViewAutomaticDimension
    

Ответ 10

Я был просто вдохновлен вашим решением и попробовал другой способ.

Попробуйте добавить tableView.reloadData() в viewDidAppear().

Это работает для меня.

Я думаю, что вещи за прокруткой "те же", что и reloadData. Когда вы прокручиваете экран, ему нравится называть reloadData(), когда viewDidAppear.

Если это работает, PLZ ответьте на этот ответ, чтобы я мог быть уверен в этом решении.

Ответ 11

Для Swift я проверил этот ответ в iOS 9.0 и iOS 11 также (Xcode 9.3)

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Здесь необходимо добавить ограничения сверху, снизу, справа и слева

Ответ 12

Для Swift 4.2

@IBOutlet weak var tableVw: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Set self as tableView delegate
    tableVw.delegate = self

    tableVw.rowHeight = UITableView.automaticDimension
    tableVw.estimatedRowHeight = UITableView.automaticDimension
}

// UITableViewDelegate Method 
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return UITableView.automaticDimension
}

Удачного кодирования :)

Ответ 13

К сожалению, я не уверен, чего мне не хватало. Вышеупомянутые методы не работают для меня, чтобы получить высоту ячейки XIB или позволить layoutifneeded() или UITableView.automaticDimension сделать вычисление высоты. Я искал и пробовал от 3 до 4 ночей, но не смог найти ответ. Некоторые ответы здесь или в другом посте дали мне подсказки для обходного пути, хотя. Это глупый метод, но он работает. Просто добавьте все свои клетки в массив. А затем установите выход каждого из ваших ограничений по высоте в раскадровке xib. Наконец, добавьте их в метод heightForRowAt. Это просто, если вы не знакомы с этими API.

Swift 4.2

CustomCell.Swift

@IBOutlet weak var textViewOneHeight: NSLayoutConstraint!
@IBOutlet weak var textViewTwoHeight: NSLayoutConstraint!
@IBOutlet weak var textViewThreeHeight: NSLayoutConstraint!

@IBOutlet weak var textViewFourHeight: NSLayoutConstraint!
@IBOutlet weak var textViewFiveHeight: NSLayoutConstraint!

MyTableViewVC.Swift

.
.
var myCustomCells:[CustomCell] = []
.
.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = Bundle.main.loadNibNamed("CustomCell", owner: self, options: nil)?.first as! CustomCell

.
.
myCustomCells.append(cell)
return cell

}


override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

   let totalHeight = myCustomCells[indexPath.row].textViewOneHeight.constant + myCustomCells[indexPath.row].textViewTwoHeight.constant +  myCustomCells[indexPath.row].textViewThreeHeight.constant + myCustomCells[indexPath.row].textViewFourHeight.constant + myCustomCells[indexPath.row].textViewFiveHeight.constant

  return totalHeight + 40 //some magic number


}

Ответ 14

Я пользуюсь этим

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return 100
}

Ответ 15

В моем случае - в раскадровке у меня было две метки, как на картинке ниже, обе метки имели желаемые значения ширины, прежде чем я сделал их равными. как только вы отмените выбор, он изменится на автоматический, и, как обычно, наличие вещей должно работать как шарм.

1.rowHeight = UITableView.automaticDimension, and
2.estimatedRowHeight = 100(In my case).
3.make sure label number of lines is zero.

enter image description here

Ответ 16

Я также получил эту проблему изначально, я решил свою проблему из этого кода, попробуйте избежать использования self.tableView.reloadData() вместо этого кода для динамической высоты

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];

Ответ 17

Вы должны просто установить все ограничения для TOP, BOTTOM и ВЫСОТА для каждого объекта в представлении/просмотре ячеек и удалить существующий средний Y положение если есть. Потому что, где вы этого не сделали, помещает артефакты в другие виды.

Ответ 18

Для цели c это одно из моих хороших решений. это сработало для меня.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.textLabel.text = [_nameArray objectAtIndex:indexPath.row];
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}

Нам нужно применить эти 2 изменения.

1)cell.textLabel.numberOfLines = 0;
  cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;

2)return UITableViewAutomaticDimension;

Ответ 19

В дополнение к тому, что сказали другие,

УСТАНАВЛИВАЙТЕ СВОЮ ЭТИКЕТКУ, ОТНОСЯЩУЮСЯ К НАДЗОРУ!

Поэтому вместо того, чтобы размещать ограничения на метки относительно других вещей вокруг него, ограничьте его представлением содержимого ячейки табличного представления.

Затем убедитесь, что высота метки установлена более или равна 0, а количество строк установлено в 0.

Затем в ViewDidLoad добавьте:

tableView.estimatedRowHeight = 695

tableView.rowHeight = UITableViewAutomaticDimension

Ответ 20

При использовании статического UITableView я устанавливаю все значения в UILabel и затем вызываю tableView.reloadData().

Ответ 21

Это просто, когда вы делаете 2 вещи:

  1. настройка автоматической высоты

    tableView.rowHeight = UITableView.automaticDimension

  2. создание всех таблиц TableViewCell с ограничениями FULL сверху вниз. Последний элемент ** ДОЛЖЕН ** определять некоторый нижний интервал для окончания ячейки.

Таким образом, механизм компоновки может вычислить высоту ячейки и правильно применить значение.

Ответ 22

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 88.0

И не забудьте добавить нижние ограничения для метки

Ответ 23

self.Itemtableview.estimatedRowHeight = 0;
self.Itemtableview.estimatedSectionHeaderHeight = 0;
self.Itemtableview.estimatedSectionFooterHeight = 0;


[ self.Itemtableview reloadData];
self.Itemtableview.frame = CGRectMake( self.Itemtableview.frame.origin.x,  self.Itemtableview.frame.origin.y,  self.Itemtableview.frame.size.width,self.Itemtableview.contentSize.height + self.Itemtableview.contentInset.bottom + self.Itemtableview.contentInset.top);

Ответ 24

Установите соответствующие ограничения и обновите методы делегирования как:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Это решит проблему с динамической высотой ячейки. ЕСЛИ вам не нужно проверять ограничения.

Ответ 25

вы можете использовать мой метод ниже, и он работает для меня, чтобы сделать динамическую высоту UITableviewCell

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 100.0
    }

Вы можете установить возвращаемое значение вышеуказанного метода, как вы хотите.