Анимация NSTableView с начальным и конечным состояниями массива - PullRequest
2 голосов
/ 30 ноября 2011

Я искал NSTableView moveRowAtIndex:toIndex метод для анимации строк в таблице. Это не очень полезно для сортировки, хотя из того, что я могу сказать. Моя интерпретация того, как это работает, заключается в следующем: если я хочу переместить строку 0 в строку 4, то строки между ними обрабатываются соответствующим образом. Однако, если у меня есть табличное представление с массивом, поддерживающим его, и затем я сортирую массив, я хочу, чтобы табличное представление анимировалось из старого состояния в новое состояние. Я не знаю, какие предметы были перемещены по сравнению с теми, которые сдвигаются, чтобы приспособить перемещенные.

Пример:

[A,B,C,D] --> [B,C,D,A]

Я знаю, что строка 0 переместилась в строку 3, поэтому я бы сказал [tableView moveRowAtIndex:0 toIndex:3]. Но если я применил некоторую пользовательскую операцию сортировки к [A, B, C, D], чтобы она выглядела как [B, C, D, A], я на самом деле не знаю, что строка 0 переместилась в строку 3, а не в строки 1 , 2 и 3 перемещаются в строки 0, 1 и 2. Я думаю, что я должен просто указать все движения (строка 0 перемещена в строку 4, строка 1 перемещена в строку 0 и т. Д.), Но анимация не выглядит правильно, когда я пытаюсь это сделать.

Есть ли лучший способ сделать это?

Редактировать: я нашел этот сайт , который, кажется, делает то, что я хочу, но кажется немного большим для чего-то, что должно быть простым (по крайней мере, я думаю, что это должно быть простым)

1 Ответ

5 голосов
/ 30 ноября 2011

Документация для moveRowAtIndex: toIndex: говорит: «Изменения происходят постепенно, по мере их отправки в таблицу».

Значение «постепенно» можно лучше всего проиллюстрировать с помощью преобразования из ABCDE в ECDAB.

Если вы просто рассмотрите начальный и конечный индексы, это выглядит так:

E: 4->0
C: 2->1
D: 3->2
A: 0->3
B: 1->4

Однако при постепенном выполнении изменений «начальные» индексы могут перемещаться по мере преобразования массива:

E: 4->0 (array is now EABCD)
C: 3->1 (array is now ECABD)
D: 4->2 (array is now ECDAB)
A: 3->3 (array unchanged)
B: 4->4 (array unchanged)

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

Вот очень простая реализация, которая берет произвольно отсортированный массив и «воспроизводит» ходы, необходимые для преобразования исходного массива в отсортированный массив:

// 'backing' is an NSMutableArray used by your data-source
NSArray* sorted = [backing sortedHowYouIntend];

[sorted enumerateObjectsUsingBlock:^(id obj, NSUInteger insertionPoint, BOOL *stop) {

  NSUInteger deletionPoint = [backing indexOfObject:obj];

  // Don't bother if there's no actual move taking place
  if (insertionPoint == deletionPoint) return;

  // 'replay' this particular move on our backing array
  [backing removeObjectAtIndex:deletionPoint];
  [backing insertObject:obj atIndex:insertionPoint];

  // Now we tell the tableview to move the row
  [tableView moveRowAtIndex:deletionPoint toIndex:insertionPoint];
}];
...