Как разрешить UITableViewCell выключить содержимое смещения контента? - PullRequest
0 голосов
/ 18 января 2019

У меня есть UITableView, который содержит кучу ячеек.

Если пользователь нажимает на вторую ячейку, предполагается, что первая ячейка должна анимировать, значительно увеличить ее высоту и сдвинуть все остальные ячейки вниз, оставив положение прокрутки пользователя в том же месте. Мой код работает на 100% правильно, когда обе ячейки на экране. ContentSize UITableView значительно увеличивается, а contentOffset не изменяется.

Но если пользователь прокручивает страницу вниз, чтобы была видна только вторая ячейка, при нажатии на нее первая ячейка расширяется за пределы экрана, и для пользователя ничего не происходит.

contentSize UITableView не изменяется, равно как и contentOffset. Как только пользователь слегка прокручивает вверх и видит дно расширенной ячейки, contentSize и contentOffset обновляются, отражая тот факт, что первая ячейка действительно намного больше (но с точки зрения пользователя ничего не меняется)

Вызов heightForRowAtIndexPath для пути индекса ячейки до и после расширения возвращает ожидаемые значения.

В моем коде многое происходит, но основная часть, которая должна анимировать расширение, находится здесь:

UIView animateWithDuration:0.3
 animations:^{
   performSelectorOnMainThread(@selector(updateItemHeights:), withObject: nil, waitUntilDone: YES)
 }
 completion:^(BOOL finished){}]

И реализация updateItemHeights:

   beginUpdates
   endUpdates
   self.contentSize = sizeThatFits([contentSize.width, CGFLOAT_MAX])

Похоже, iOS пытается удержать пользователя в его текущем контексте, позволяя ячейкам расширяться.

Как получить ячейку за пределами экрана, чтобы оттолкнуть другие ячейки?

1 Ответ

0 голосов
/ 28 января 2019

Благодаря системе удаления табличных представлений, когда ячейка не видна, она не загружается. Поэтому представление таблицы не будет анимировать изменение, если оно не отображается на экране.

Здесь я вижу 2 варианта:

Прокрутка до анимированной ячейки перед обновлением ее высоты

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let animatedIndexPath = ...
    let visibleRows = tableView.indexPathsForVisibleRows ?? []
    if visibleRows.contains(animatedIndexPath) {
        self.tableView.reloadRows(at: [animatedIndexPath], with: .automatic)
    } else {
        UIView.animate(withDuration: 0.3, animations: {
            self.tableView.scrollToRow(at: animatedIndexPath, at: .none, animated: false)
        }) { _ in
            self.tableView.reloadRows(at: [animatedIndexPath], with: .automatic)
        }
    }
}

Настройка смещения содержимого после обновления ячейки

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let animatedIndexPath = ...
    let visibleRows = tableView.indexPathsForVisibleRows ?? []
    if visibleRows.contains(animatedIndexPath) {
        self.tableView.reloadRows(at: [animatedIndexPath], with: .automatic)
    } else {
        let offset = tableView.contentOffset
        tableView.reloadData()
        tableView.layoutIfNeeded() // forces the new offset computation
        tableView.setContentOffset(offset, animated: true)
    }
}

(могут возникнуть некоторые проблемы из-за динамического вычисления высоты табличного представления, отключите его tableView.estimatedRowHeight = 0)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...