Проблема динамической высоты для ячеек UITableView (Swift)
Динамический текст переменной длины вставляется в метки ячейки таблицы. Для того, чтобы высоты ячеек таблицы видны динамически, я реализовал в viewDidLoad()
:
self.tableView.estimatedRowHeight = 88.0
self.tableView.rowHeight = UITableViewAutomaticDimension
Это хорошо работает для ячеек, которые еще не прокручиваются (поскольку UITableViewAutomaticDimention
вызывается при прокрутке в ячейку), но не для ячеек, которые изначально отображаются на экране при загрузке таблицы с данными.
Я попробовал просто перезагрузить данные (как было предложено во многих других ресурсах):
self.tableView.reloadData()
как в viewDidAppear()
, так и viewWillAppear()
, и это было бесполезно. Я потерял.. кто-нибудь знает, как иметь xcode визуализировать динамическую высоту для ячеек, загруженных изначально на экран?
Пожалуйста, дайте мне знать, если есть лучший альтернативный метод.
Ответы
Ответ 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 вещи
Это - замечательное учебное пособие по самостоятельной калибровке (ячейки с динамическим табличным представлением), написанное в быстрой версии.
Ответ 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 вещи:
настройка автоматической высоты
tableView.rowHeight = UITableView.automaticDimension
создание всех таблиц 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
}
Вы можете установить возвращаемое значение вышеуказанного метода, как вы хотите.