UITableView оживляет строку, переупорядочивающую сортировку

У меня есть таблица, которую пользователи могут сортировать по-разному. Когда пользователи меняются между этими двумя режимами сортировки, я хочу, чтобы повторная сортировка была анимирована. И хотя методы UITableView предоставляют поддержку анимации для вставки, удаления и перезагрузки строк, я не вижу ничего, что позволяет мне оживлять движение строки.

Я что-то пропустил?

Предполагая, что я нет, есть ли у кого-нибудь образец кода, как это сделать?

Спасибо.

Ответы

Ответ 1

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

My TableView получает свои данные из массива с именем _objects. В моем методе сортировки я начинаю с создания другого массива, который является точной копией массива данных:

    NSArray *objectsBeforeSort = [NSArray arrayWithArray:_objects];

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

[self.tableView beginUpdates];

for (int i = 0; i < _objects.count; i++)
{
    // newRow will get the new row of an object.  i is the old row.
    int newRow = [_objects indexOfObject:objectsBeforeSort[i]];
    [self.tableView moveRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] toIndexPath:[NSIndexPath indexPathForRow:newRow inSection:0]];
}


[self.tableView endUpdates];

Я еще не тестировал этот код, но он, похоже, дает желаемый результат.

Ответ 2

Вы пытались использовать moveRowAtIndexPath: toIndexPath: внутри блока beginUpdates-endUpdates? Кажется, это то, что в настоящее время рекомендуют документы разработчиков. Если это не работает само по себе, вы также можете попробовать его обернуть в блок [UIView animateWithDuration: animations:].

Ссылка на документацию ADC для UITableView: https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITableView

Ответ 3

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

  • Все значения в массиве предполагаются уникальными. Список чисел, где один и тот же номер встречается несколько раз, будет возвращать один и тот же индекс для каждого экземпляра этого номера.

  • Сортировка выполняется в новый массив. Требования к памяти удваиваются.

  • Алгоритм неэффективен. Для каждого значения в отсортированном массиве исходный массив сканируется на предмет происхождения значения.

  • Даже с эффективным алгоритмом, кто хочет видеть 10000 анимированных строк? Создание 10000 просмотров, даже 500 просмотров, было бы нежелательным.

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

Это решение более эффективно, но издержки отслеживания движений индекса нетривиальны, когда алгоритм быстрой сортировки настолько эффективен. Выделение необходимого пространства в массиве заранее уменьшит его до некоторой степени. Кроме того, он работает только тогда, когда резервное хранилище является массивом. Это не работает, если вы делаете сортировку по основным данным. Я бы, вероятно, делал анимацию только в том случае, если в таблице было менее 1000 значений.