UITableView анимация свертывания ячейки выглядит плохо - PullRequest
0 голосов
/ 23 мая 2018

У меня проблема с тем, чтобы анимация коллапса клеток выглядела плавно.

Изображение стоит тысячи слов.Вот два GIF-изображения одного и того же табличного представления:

Great Terrible

Свертывание работает очень хорошо для ячейки "6", ноне для "5".Похоже, что весь контент UITableView подпрыгивает перед выполнением анимации свертывания.

Я не , использующий UITableViewAutomaticDimension для UITableView rowHeight.Вместо этого я предоставляю высоту строки методом tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) и расширяю / сворачиваю ячейку, используя табличное представление beginUpdates / endUpdates.Как вы можете видеть, я также прокручиваю к расширенной строке, используя tableView.scrollToRow(at: indexPath, at: .none, animated: true) (но только при расширении, так что это, вероятно, не имеет значения).

Подкласс UITableViewController встроен в UINavigationController с большим заголовком ипанель поиска (здесь не видно, потому что содержимое прокручивается вниз).UINavigationController встроен в UITabBarController.

Вот соответствующая часть раскрытия / свертывания.При передаче параметра nil indexPath уже развернутая ячейка свернется.

func expandRow(at indexPath: IndexPath?) {
    selectedIndexPath = indexPath
    tableView.beginUpdates()
    tableView.endUpdates()

    if let ip = indexPath {
        tableView.scrollToRow(at: ip, at: .none, animated: true)
    }
}

Этот метод вычисляет высоту строки и вызывается как tableView(_:heightForRowAt:) и tableView(_:estimatedHeightForRowAt:):

private func heightForRow(at indexPath: IndexPath) -> CGFloat {
    var height: CGFloat
    if selectedIndexPath == indexPath {
        // Add some height variety
        height = 300 + CGFloat((indexPath.row % 4) * 20)
    } else {
        height = 70
    }
    return height
}

Вот репозиторий GitHub: https://github.com/AleksanderMaj/CellCollapse

Есть идеи, как это улучшить?

Эта проблема чувствительна к размерам (эта проблема может не воспроизводиться после выполнения тех же действий на устройстве сдругой размер экрана).Это было записано на имитаторе iPhone 7 с iOS 11.3.


РЕДАКТИРОВАТЬ 1: Важно сохранить автоматическую прокрутку к расширенной ячейке.

Ответы [ 4 ]

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

Возникла эта проблема при изменении размера моей строки для каждого щелчка строки.Почти то же самое с ответом @Taras, хотя здесь необходимо сначала удалить анимацию, прежде чем назначать сохраненный contentOffset.Надеюсь, это поможет:)

func expandRow() {
    let savedContentOffset = tableView.contentOffset

    tableView.beginUpdates()
    tableView.endUpdates()
    tableView.layer.removeAllAnimations()

    tableView.setContentOffset(savedContentOffset, animated: false)
}
0 голосов
/ 23 мая 2018

Я смог сделать гладко с небольшим изменением в вашем методе расширения:

func expandRow(at indexPath: IndexPath?) {
    selectedIndexPath = indexPath
    tableView.beginUpdates()
    tableView.endUpdates()

    if let ip = indexPath {
        tableView.scrollToRow(at: ip, at: .middle, animated: true)
    }
}

Before After

0 голосов
/ 19 декабря 2018

У меня есть идея.Я не уверен, что уловка работает, как я думал.

Складная таблица имеет функцию, которая изменяет высоту представления таблицы при ее расширении или свертывании.

Если мы используем настраиваемое представлениеунаследованный от UITableView, мы можем переопределить свойство view, contentSize и contentOffset.Переопределив эти два свойства, мы можем на некоторое время остановить табличное представление, отключить прокрутку.

var contentSizeChanging: Bool = false

override var contentSize: CGSize {
    willSet {
        contentSizeChanging = true
    }
    didSet {
        contentSizeChanging = false
    }
}

override var contentOffset: CGPoint {
    get {
        return super.contentOffset
    }
    set(newValue) {
        if contentSizeChanging { return }
        super.contentOffset = newValue
    }
}
0 голосов
/ 23 мая 2018

Вы прокручиваете к расширенной строке, и это делает UITableView немного перескочившим.

Итак, вот рефакторированный expandRow(at:) метод:

func expandRow(at indexPath: IndexPath?) {
    self.contentOffset = self.tableView.contentOffset
    selectedIndexPath = indexPath
    tableView.beginUpdates()
    tableView.endUpdates()

    if let contentOffset = self.contentOffset {
        tableView.contentOffset = contentOffset
    }
}

также вам нужно добавить var contentOffset: CGPoint?для вашего контроллераОбновленный пример кода

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