Как получить высоту UITableView, когда ячейки имеют динамический размер?
У меня есть UITableView с ячейками с динамическим размером. Это означает, что я установил:
tableView.estimatedRowHeight = 50.0
tableView.rowHeight = UITableViewAutomaticDimension
Теперь я хочу получить высоту всего представления таблицы. Я попытался получить его через tableView.contentSize.height
, но это возвращает только примерную высоту строки, а не фактическую динамическую высоту представления таблицы.
Как получить динамическую высоту всего представления таблицы?
Ответы
Ответ 1
Я, наконец, взломал решение:
tableView.contentSize.height
не будет работать для динамических ячеек, потому что они возвратят только число ячеек * estimatedRowHeight
.
Следовательно, чтобы получить высоту динамической таблицы, вы ищете все видимые ячейки и суммируйте их высоты. Обратите внимание, что это работает только для табличных представлений, которые короче экрана.
Однако, прежде чем мы сделаем это для поиска видимых ячеек, важно знать, что примечание нам нужно получить представление таблицы на экране, чтобы мы могли получать видимые ячейки. Для этого мы можем установить ограничение высоты для представления таблицы на некоторое сколь угодно большое число, чтобы оно отображалось на экране:
-
Задайте высоту ограничения табличного представления:
// Class variable heightOfTableViewConstraint set to 1000
heightOfTableViewConstraint = NSLayoutConstraint(item: self.tableView, attribute: .height, relatedBy: .equal, toItem: containerView, attribute: .height, multiplier: 0.0, constant: 1000)
containerView.addConstraint(heightOfTableViewConstraint)
-
Вызовите tableView.layoutIfNeeded(), и когда закончите, найдите видимые ячейки, суммируйте их высоту и отредактируйте heightOfTableViewConstraint
:
UIView.animate(withDuration: 0, animations: {
self.tableView.layoutIfNeeded()
}) { (complete) in
var heightOfTableView: CGFloat = 0.0
// Get visible cells and sum up their heights
let cells = self.tableView.visibleCells
for cell in cells {
heightOfTableView += cell.frame.height
}
// Edit heightOfTableViewConstraint constant to update height of table view
self.heightOfTableViewConstraint.constant = heightOfTableView
}
Ответ 2
на него уже был дан ответ, но я хочу поделиться своим опытом.
У меня та же проблема. Я искал ответы во многих похожих вопросах и пытался их ответы и не работал.
Наконец, я нашел leonardloo answer. Большое спасибо, но он еще не решил мою проблему. Я просто хочу закончить его ответ. Я поставил этот код из своего ответа:
UIView.animate(withDuration: 0, animations: {
self.tableView.layoutIfNeeded()
}) { (complete) in
var heightOfTableView: CGFloat = 0.0
// Get visible cells and sum up their heights
let cells = self.tableView.visibleCells
for cell in cells {
heightOfTableView += cell.frame.height
}
// Edit heightOfTableViewConstraint constant to update height of table view
self.heightOfTableViewConstraint.constant = heightOfTableView
}
в этом блоке кода:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
if indexPath.row == data.count-1{
// Insert the code here
}
return cell
}
Это означает, что после того, как все строки в таблице были загружены, мы обновляем высоту строки, используя этот фрагмент кода.
Он работает!!!
Ответ 3
Вы можете добавить это в расширениях.
Свифт 4:
extension UITableView {
// sums the height of visible cells
func heightOfVisibleCells() -> CGFloat {
return self.visibleCells.map({ $0.frame.height }).reduce(0, +)
}
}
Ответ 4
Хотя ответ @leonardloo частично верен и может удовлетворить потребности многих людей, я хотел бы поделиться тем, как я решил свою проблему.
У меня был большой tableView с большими строками, и у меня была та же проблема. Когда я применил ответ @leonardloo, я увидел, что он рисует только количество видимых ячеек, которые он обнаружил в начале, и он рисует 1 строку, тогда как он должен нарисовать 5 (мой источник данных).
Чтобы исправить это, я нашел такое простое решение:
UIView.animate(withDuration: 0, animations: {
self.tableView.layoutIfNeeded()
}) { (complete) in
var heightOfTableView: CGFloat = 0.0
// Get visible cells and sum up their heights
let cells = self.tableView.visibleCells
for cell in cells {
heightOfTableView += cell.frame.height
}
// Edit heightOfTableViewConstraint constant to update height of table view
// Set tableView constraint to height + 1 so that
// it can still draw the next visible cell it supposed to.
self.heightOfTableViewConstraint.constant = heightOfTableView + 1
}
Смысл здесь в том, чтобы позволить ему нарисовать следующую ячейку, чтобы она также учитывалась в visibleCells, установив константу ограничения на высоту +1. Я проверил, и теперь кажется, что это работает как шарм.
Ответ 5
Вы должны рассчитать высоту tableView в следующем методе делегата,
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
//Get the height required for the TableView to show all cells
if indexPath.row() == (tableView.indexPathsForVisibleRows.last! as! NSIndexPath).row {
//End of loading all Visible cells
float heightRequiredForTable = tableView.contentSize.height
//If cell are more than 10 or so that it could not fit on the tableView visible area then you have to go for other way to check for last cell loaded
}
}
Ответ 6
Мы можем использовать расширение UITableView для получения высоты,
extension UITableView {
///Get visible cell height
var visibleCellsHeight: CGFloat {
return visibleCells.reduce(0) { $0 + $1.frame.height }
}
}
Ответ 7
Просто сохраните массив типа CGFLoat
и добавьте UITableViewAutomaticDimension
в cellForRowAt
indexPath
делегат tableview
var cellHeight = [CGFloat]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cellHeight.append(UITableViewAutomaticDimension)
}
Ответ 8
Я добавлю свой ответ здесь, так как я немного боролся с этим.
В моем табличном представлении использовались разделы с заголовками, поэтому просто получить высоту видимых ячеек не получалось. В итоге я установил очень большую высоту для tableView
чтобы все содержимое было добавлено. Затем в последней cell
tableView
я tableView
размер tableView
чтобы он соответствовал высоте его content
.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
... // do your normal cell processing
// determine height and change it
if indexPath.section == (self.sectionTitles.count - 1) && indexPath.row == (sectionData.count - 1) {
UIView.animate(withDuration: 0, animations: {
self.tableView.layoutIfNeeded()
}) { complete in
// Edit heightOfTableViewConstraint constant to update height of table view
self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
}
}
}
Ответ 9
вы можете попробовать этот код
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}