#ios #swift #uitableview #uitableviewautomaticdimension
Вопрос:
Есть 5 статических ячеек. Когда я показываю все 5 ячеек, это нормально, но если я скрою какую-то ячейку, вернув нулевую высоту, а последняя видимая ячейка не совпадает с последней ячейкой tableview в раскадровке, тогда возникает путаница в том, как это сделать ?
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return hideRow(at: indexPath) ? 0: UITableView.automaticDimension
}
IMO , если последняя видимая строка в tableview и последняя строка в tableview одинаковы
return indexPath.row == 4 ? 150 : tblHeight - 150
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if hideRow(at: indexPath) {
return 0
}
else {
let tblHeight = infoTable.bounds.size.height
if indexPath.row == 4 {
return tblHeight - yPlusHeightOfPreviousCell
}
return UITableView.automaticDimension
}
}
Но теперь проблема в том, что если 3-я строка-последняя, а для 4-й и 5-й я возвращаю 0 в качестве высоты, чтобы скрыть ее.
Тогда как сделать так, чтобы последняя видимая ячейка расширилась и заняла все пространство
Комментарии:
1. Я думаю, что вы ищете это
infoTable.tableFooterView = UIView()
, напишите это внутри viewDidLoad, чтобы удалить нижние дополнительные строки. Или, используя свой подходindexPath.row == arrayData.count - 1
, сравните последний индекс.2. Привет , я хочу, чтобы последнее видимое занимало остальное пространство. так, чтобы он появлялся в нижней части экрана
3. Я хотел бы показать последнюю видимую строку, которая займет оставшееся место. Допустим , третий индекс виден последним, а 4-я и 5-я высоты равны нулю, следовательно, он не будет виден. Теперь, как я могу убедиться, что третья строка занимает всю высоту просмотра таблицы
Ответ №1:
Добавьте пустое UIView
представление в качестве нижнего колонтитула таблицы:
class StaticTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
}
}
Отредактируйте После повторного прочтения вашего вопроса…
Приведенный выше код «скроет» пустые строки.
Если ваша цель состоит в том, чтобы «последняя видимая строка» заполнила оставшуюся высоту, это будет значительно сложнее.
Поскольку в вашем текущем подходе используется статическое представление таблицы, и вы не будете выполнять прокрутку, гораздо проще было бы использовать a UIStackView
с пользовательскими представлениями вместо ячеек. Тогда все будет обрабатываться автоматической компоновкой, ограничениями и представлением стека, и вам не нужно будет выполнять никаких вычислений.
Изменить 2a — переместить код в функцию
Добавьте эти переменные в класс контроллера табличного представления:
var numRows: Int = 5
var lastVisibleRow: Int = -1
var lastRowHeight: CGFloat = -1
var curTableWidth: CGFloat = 0
Добавьте эту функцию:
func updateTable() -> Void {
lastVisibleRow = -1
var h: CGFloat = 0
// find last visible row
// and sum of row heights
for i in 0..<numRows {
let r = tableView.rectForRow(at: IndexPath(row: i, section: 0))
h = r.height
if r.height > 1.0 {
lastVisibleRow = i
}
}
// get rect of last visible row
let r = tableView.rectForRow(at: IndexPath(row: lastVisibleRow, section: 0))
// subtract its height from the sum of heights
h -= r.height
// set calculated last row height
lastRowHeight = tableView.frame.height - h tableView.bounds.origin.y
// reload the last visible row
//tableView.reloadRows(at: [IndexPath(row: lastVisibleRow, section: 0)], with: .none)
tableView.reloadData()
}
Вызывайте его в viewDidLayoutSubviews()
любое время, когда меняется ширина таблицы:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// we only run the following block
// if the tableView width has changed
if curTableWidth != tableView.frame.width {
curTableWidth = tableView.frame.width
updateTable()
}
}
и измените свой heightForRowAt
на этот:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if hideRow(at: indexPath) {
// row should be hidden
return 0
} else if indexPath.row == lastVisibleRow {
// if it's the last visible row,
return lastRowHeight
}
// else
return UITableView.automaticDimension
}
Затем в любое время, когда вы изменяете строки (на основе взаимодействия с пользователем или чего-либо еще), вызывайте reloadData
TableView, а затем вызывайте updateTable()
для повторного вычисления последней видимой строки и ее высоты.
Комментарии:
1. Да , вы правы, но здесь мне придется придерживаться Tableview в результате устаревшего кода. Моя цель состоит в том, чтобы «последняя видимая строка» заполнила оставшуюся высоту. Любые предложения приветствуются
2. @RaviMan — ну, потенциально есть много «движущихся частей», с которыми нужно иметь дело. Когда вы определяете, какие строки показывать? В
viewDidLoad()
? Или вы показываете/скрываете строки динамически в зависимости от взаимодействия с пользователем? Являются ли ваши статические ячейки фиксированной высоты или высота может варьироваться в зависимости от ширины обзора? Я бы предложил отредактировать ваш вопрос и включить содержимое ячеек «реального мира» (я предполагаю, что опубликованное вами изображение на самом деле не то, что вы планируете отображать), а также более подробную информацию о том, как и когда вы определяете, какие строки вы хотите показывать и скрывать.3. HeightForRowAtIndex… вот где я решаю, что показывать(автоматическое определение в качестве высоты) и что скрывать(0 в качестве высоты), основываясь на бизнес-логике для конкретного indexpath.
4. @RaviMan — ну, нет… вы устанавливаете высоту строки в
heightForRowAt
… предположительно, у вас где-то есть какие-то данные, которые заданы перед этим вызовом иhideRow(at: indexPath)
возвращают значение true или false на основе этих данных. Итак, где / когда вы устанавливаете эти данные?5. @RaviMan — возможно, вы сможете использовать этот код для своих нужд. См. раздел » Редактирование 2a » для расположения кода и примечаний.