Статическое представление таблицы Как сделать так, чтобы последняя видимая строка занимала оставшееся место в

#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 » для расположения кода и примечаний.