Проблемы с расширением UITableView - PullRequest
1 голос
/ 16 января 2020

Цель и фон

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

Вот как это выглядит: ссылка

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


Вопрос

Как бы я убрал этот глюк или лучше выполнил sh эту задачу?


Код

Вот моя иерархия:

+-- ParentVC
|   +-- ParentView
|   |   +-- CustomTableVC's View
|   |   |   +-- Custom UITable

(CustomTableVC is a child of ParentVC)

Вот так я перезагружаю отрезанный участок и устанавливаю новую высоту

// === CustomTableVC === //
func toggleSection(_ header: PTTableHeader, section: Int) {

       ...

       // Reload the section with a drop-down animation
       table.reloadSections(NSIndexSet(index: section) as IndexSet, with: .automatic)

       // Update the height of the container view
       preferredContentSize.height = table.contentSize.height
}

// Height for section headers and rows: 44 (including estimated)

А вот как родитель обновляется:

// === ParentVC === //
override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
       super.preferredContentSizeDidChange(forChildContentContainer: container)
       if let child = container as? PTTable {
              customTableVC.view.layoutIfNeeded()
              customTableViewHeightAnchor.constant = child.preferredContentSize.height
              UIView.animate(withDuration: 3, animations: {
                     view.layoutIfNeeded()
              })
       }
       // Height anchor starts at parentView's height / 3 because 
       //  I'm not sure how to make it match the table's contentSize from the get-go
}

Удаление view.layoutIfNeeded() приводит к тому, что последний раздел не выполняет анимацию вставки, но все равно сбрасывает .


Работает на iPhone 11 Pro (симулятор).

1 Ответ

0 голосов
/ 27 января 2020

Отражение

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


Решение

По сути, я устанавливаю предпочитаемый параметр ContentSize до перезагрузки разделов. Это предупреждает ParentV C о начале анимации до того, как что-либо действительно изменится. Это означает, что в таблице теперь есть место для перемещения нижней части без необходимости ее перезагрузки.


Код

// === CustomTableVC === //
func toggleSection(_ header: PTTableHeader, section: Int) {

       ...

       // Predict the height of the table BEFORE reloading it
       predictHeight(section: section, willExpand: isExpanding) // Change isExpanding with whatever Bool is tracking the expand/collapse state of the section

       // THEN reload the section with a drop-down animation
       table.reloadSections(NSIndexSet(index: section) as IndexSet, with: .automatic)

       // Optionally do the above with an animation using UIView.animate() or UIView.transition()

       // And FINALLY update the height of the container view
       // This one is probably optional, but it will be more exact depending on what methods you use to predict the height in predictHeight()
       preferredContentSize.height = table.contentSize.height
}

func predictHeight(section: Int, willExpand: Bool) {
        // Get the heights of all the known headers/footers/rows
        let tableSectionsHeight = CGFloat(table.numberOfSections) * (table.estimatedSectionHeaderHeight + table.sectionFooterHeight)
        let tableCellsHeight = CGFloat(table.visibleCells.count) * table.estimatedRowHeight

        // Calculate the height of the section being expanded/collapsed
        // With the method I used, I can't just do table.numberOfRows(inSection: Int) since expanding/collapsing is essentially just adding/removing those rows
        // Instead I need to store a reference to the number of rows per section and access it via that array, object, etc.
        let sectionContentHeight = willExpand ? CGFloat(rowCounts[section]) * table.estimatedRowHeight : 0 // 0 if collapsing

        // Set the preferredContentSize so that the ParentVC picks it up 
        preferredContentSize.height = tableSectionsHeight + tableCellsHeight + sectionContentHeight
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...