Вставка строк в верхнюю часть UITableView приводит к смещению строк вниз, что приводит к плохой анимации - PullRequest
0 голосов
/ 24 апреля 2018

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

Допустим, у пользователя 100 сообщений, а размер моей страницы равен 20. Когда пользователь попадает на страницу, я показываю последнюю страницу (сообщенияот 80 до 100).

Когда пользователь медленно прокручивает вверх, я получаю предыдущую страницу (60 - 80), когда indexPath willDisplay становится indexPath.row = 0 && indexPath.section = 0.Я строю массив dataSource и вызываю insertRows:at:with:.Проблема, с которой я сталкиваюсь, заключается в том, что когда я вставляю строки, он начинается с indexPath.row = 0 && indexPath.section = 0, что вызывает его предварительную выборку предыдущей страницы, что приводит к преждевременной предварительной выборке остальных страниц.У меня может быть флаг, чтобы избежать этого, но он по-прежнему отталкивает остальные ячейки, вызывая потерю позиции прокрутки, а затем возвращается, что приводит к вспыхивающей анимации.

Я использую rowHeight = UITableViewAutomaticDimension для вычисления ячейкивысота.

Я экспериментировал с вызовами на scrollToRow(at:at:animated), но он все еще нажимает при вызове insertRows:.

Я знаю, что это теоретически возможно, потому что такие приложения, как Whatsapp и iMessage, имеют этоповедение (при условии, что они используют tableView), и они работают хорошо.

Вот суть того, что у меня есть:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if !insertingRows && indexPath.section == 0 && indexPath.row == 0 {
        loadData()
    }
}

private func loadData() {
    dataSource.load({ [weak self] (success: Bool, error: Error?) in
        guard let strongSelf = self else {
            return
        }

        let newMessagesCount = 20 // testing
        var indices = [IndexPath]()
        for index in stride(from: 0, to: newMessagesCount, by: 1) {
            indices.append(IndexPath(row: index, section: 0))
        }

        DispatchQueue.main.async {
            strongSelf.insertingRows = true
            UIView.setAnimationsEnabled(false)
            strongSelf.tableView.insertRows(at: indices, with: .none)
            UIView.setAnimationsEnabled(true)
            strongSelf.insertingRows = false
        }
    })
}

1 Ответ

0 голосов
/ 24 апреля 2018

Вместо использования функции вставки строк tableView, вы можете просто добавить элементы в источник данных.Затем вы можете заменить код в вашей функции DispatchQueue.main.async приведенным ниже кодом.

let oldContentHeight: CGFloat = tableView.contentSize.height
let oldOffsetY: CGFloat = tableView.contentOffset.y
tableView.reloadData()
let newContentHeight: CGFloat = tableView.contentSize.height
tableView.contentOffset.y = oldOffsetY + (newContentHeight - oldContentHeight)

См. Эту суть, которую я нашел для получения дополнительной информации: https://gist.github.com/WorldDownTown/9ed681148e9224f7157c9e8620ce46b8

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