Анимируйте вставку нового раздела в UITableVIew

У меня есть эта кнопка на моем представлении, и когда я ее нажимаю, я вставляю новый раздел в свой табличный вид (у меня есть логическое условие в моем

-(NSInteger) numberOfSectionsInTableView:(UITableView*)tableView
{
    if (slide==TRUE) return 2;
    return 1;
}

А также в моем -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. Мой раздел добавлен как следует, но я где-то читал, что это может быть анимировано, потому что, когда я нажимаю свою кнопку, раздел добавляется, но без анимации. Я думаю, что я должен использовать этот -(void)insertSections:(NSIndexSet*)sections withRowanimation(UITableViewRowAnimation) animation, но я не нашел подходящего примера в Интернете.

Ответ 1

UITableViewRowAnimation - это перечисление, указанное в верхней части UITableView.h. Вы также можете просмотреть его в ссылке UITableView. Это немного, поэтому я просто вставьте его!

typedef enum {
    UITableViewRowAnimationFade,
    UITableViewRowAnimationRight,           // slide in from right (or out to right)
    UITableViewRowAnimationLeft,
    UITableViewRowAnimationTop,
    UITableViewRowAnimationBottom,
    UITableViewRowAnimationNone,            // available in iOS 3.0
    UITableViewRowAnimationMiddle,          // available in iOS 3.2.  attempts to keep cell centered in the space it will/did occupy
    UITableViewRowAnimationAutomatic = 100  // available in iOS 5.0.  chooses an appropriate animation style for you
} UITableViewRowAnimation;

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

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

Итак, ваша вставка может выглядеть так:

-(void)sliderValueChanged:(id)slider {
   slide = slider.on;

   [tableView beginUpdates];

   if (slider.on) {
      [tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationTop];
      // TODO: update data model by inserting new section
   } else {
      [tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationTop];
      // TODO: update data model by removing approprite section
   }

   [tableView endUpdates];
}

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

редактирует:

Я не думаю, что вам нужно позвонить reloadData. UITableView требует, чтобы ваша модель данных отражала изменения, которые вы делаете, с помощью методов вставки/удаления. Так, например, если перед вызовом insertSections:withRowAnimation: (с которым вы вставляете один раздел), ваш метод numberOfSectionsInTableView: возвратил 1, а затем после вызова он должен вернуть 2. Для этого в противном случае исключение. Именно это принудительное согласование позволяет вам (опять же, я думаю) избегать вызова reloadData - необходимые данные перезагружаются всей транзакцией beginUpdates: endUpdates: и любые обновления модели, которую вы делаете во время эта транзакция должна соответствовать индивидуальным вызовам вставки/удаления.

Удалить как грязь?

ОБНОВЛЕНИЯ

Если вы программируете явные анимации, я бы сказал, что вы можете сделать это в "обработчике завершения" (или просто запрограммировать анимацию напрямую), но это вам не доступно. Я думаю, вы можете обернуть код представления кнопок в своем собственном методе в представлении, а затем установить таймер, чтобы вызвать его через короткий промежуток времени, скажем,.2 секунды (вам нужно поэкспериментировать, чтобы увидеть, что хорошо выглядит), например.

[NSTimer scheduledTimerWithTimeInterval:.2 target:self selector:@selector(presentButton) userInfo:nil repeats:NO];

Это должно сделать трюк.

Ответ 2

Манипулирование строк и разделов в UITableView с помощью анимации становится довольно простым с использованием следующего API (акцент на последних двух):

Обновление модели данных

Вы должны обновить свою модель данных где-нибудь между beginUpdates и endUpdates. Неважно, обновляете ли вы модель данных до или после методов вставки или удаления только до тех пор, пока вы делаете это между beginUpdates и endUpdates.

Не вставляйте строки для новых разделов. Вы вставляете

При добавлении нового раздела с помощью метода insertSections:withRowAnimation: вам не нужно вызывать insertRowsAtIndexPaths:withRowAnimation:, чтобы добавить в него строки. Метод insertRowsAtIndexPaths:withRowAnimation: предназначен только для анимации существующего раздела. Аналогично, вам не нужно вызывать deleteRowsAtIndexPaths:withRowAnimation: при удалении раздела с помощью deleteSections:withRowAnimation:.

Относительно удаления и установки:

Я обычно делаю это в отдельном beginUpdates: endUpdates, однако вы можете вставлять и удалять одновременно. Просто имейте в виду, что UITableView будет сначала пытаться удалить строки/разделы и , а затем попытаться вставить их независимо от того, какой заказ вы выполняете в своем коде.

Обсуждение часть deleteRowsAtIndexPaths:withRowAnimation:

Обратите внимание на поведение этого метода, когда он вызывается в анимации блок, определенный методами beginUpdates и endUpdates. UITableView откладывает любые вставки строк или разделов до тех пор, пока не обработает удаление строк или разделов. Это происходит независимо от порядка вызовов метода вставки и удаления. Это не похоже на вставку или удаление элемента в изменяемом массиве, где операция может повлиять индекс массива, используемый для последовательной вставки или удаления операция. Подробнее об этом можно узнать в разделе "Вставка и удаление партии" строк и разделов "в Руководстве по программированию таблиц для iOS.

Пример вставки в раздел:

int indexOfNewSection = 4; // TODO: change to meaningful value
[self.tableview beginUpdates];
[self.tableview insertSections:[NSIndexSet indexSetWithIndex:indexOfNewSection]
              withRowAnimation:UITableViewRowAnimationAutomatic];

// Update data model
[self.sections insertObject:sectionObj atIndex:indexOfNewSection];

[self.tableview endUpdates];

Ответ 3

- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation

Указанный метод, безусловно, сделает магию.

Вероятно, вы можете попробовать следующее:

[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];

Написание прямо из моего ума. Надеюсь, это поможет...

Обратите внимание:

  • Можно использовать любой из UITableViewRowAnimation.
  • sectionIndex в указанном коде есть NSInteger. Вероятно, в вашем случае 1.