Анимация [tableView reloadData]

У меня есть UITableViewCell, который расширяется и добавляет метку при нажатии.

Логика:

Я добавил метку в cellForRowAtIndexPath к выбранной ячейке, а в didSelectRow... перезагрузил tableView. В heightForRow... выбранная ячейка расширяется. Надеюсь, вы получите картину.

В didSelectRow... мне приходится перезагружать данные, а не начинать/заканчивать обновление. Что я хочу сделать, так это перезагрузить данные и анимировать их. Я могу сделать так:

[UIView transitionWithView: tableView
                  duration: 0.40f
                   options: UIViewAnimationOptionTransitionCrossDissolve
                animations: ^(void)
 {
   [self.tableView reloadData];
 }
                completion: nil
 }];

Таким образом, происходит перекрестное растворение клеток, которые меняются. То, что я хочу, это UITableViewRowAnimationTop, но, видимо, это невозможно в параметрах перехода. Есть ли способ reloadData и использовать UITableViewRowAnimationTop?


person Community    schedule 05.02.2015    source источник
comment
Вызов reloadData уничтожает все ячейки, находящиеся в настоящее время в представлении таблицы, и восстанавливает все с нуля. Возможно, вы ищете другой метод, если это не то поведение, которое вам нужно.   -  person Ian MacDonald    schedule 05.02.2015
comment
Значит, нельзя использовать UITableViewRowAnimationTop с reloadData?   -  person    schedule 05.02.2015
comment
Вы пытались использовать beginUpdates и блокировка обновления?   -  person matt    schedule 05.02.2015
comment
Вы имеете в виду [tableView beginUpdates]; [конечные обновления tableView]?   -  person    schedule 05.02.2015
comment
Немного опоздали на эту вечеринку — судя по вашему описанию, вы хотите, чтобы ячейка росла и помещалась в новую метку. Современный подход для этого заключается в использовании ячеек с автоматическим изменением размера и автоматической настройкой макета. Если вы используете ячейки с собственным размером, вы можете просто сделать: tableView.beginUpdates(); tableView.endUpdates() и ячейки будут расширяться по мере необходимости, чтобы соответствовать их текущему содержимому. Никаких перезагрузок не требуется (если не изменился действительный набор путей к индексу таблицы). Вы можете найти более подробную информацию о подходе к этому здесь.   -  person Benjohn    schedule 23.11.2017


Ответы (5)


[UITablewView reloadData:] нельзя анимировать. Однако вы можете попробовать перезагрузить tableView, перезагрузив все разделы с анимацией.

NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [tableView numberOfSections])];

[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationAutomatic];

Хорошо, я солгал. Его можно анимировать, но для этого требуется много знаний о QuartzCore Framework работает с компонентами пользовательского интерфейса.

@import QuartzCore;

[self.tableView reloadData];

CATransition *transition = [CATransition animation];
transition.type = kCATransitionPush;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.fillMode = kCAFillModeForwards;
transition.duration = 0.6;
transition.subtype = kCATransitionFromTop;

[self.tableView.layer addAnimation:transition forKey:@"UITableViewReloadDataAnimationKey"];
person ozgur    schedule 05.02.2015
comment
Нет animation интеллектуального инспектора xcodes. - person ; 06.02.2015
comment
Я не понял, что вы имели в виду. CATransition имеет метод класса с именем transition. Вы уверены, что не пишете CATransaction? - person ozgur; 06.02.2015
comment
Вы правы, я использовал CATransaction. Я только что попробовал, и что происходит, весь tableView отключается, а затем снова загружается, и таблица даже не перезагружается? - person ; 06.02.2015

Гораздо более простое решение, не требующее CoreAnimation.

Свифт 3:

UIView.transition(with: self.view,
                  duration: 0.15,
                  options: [.curveEaseInOut, .transitionCrossDissolve],
                  animations: {
                      self.tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
}, completion: nil)
person brandonscript    schedule 30.01.2016

Решение Swift 4 с QuartzCore

import QuartzCore

tableView.reloadData()

let transition = CATransition()
transition.type = kCATransitionPush
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.fillMode = kCAFillModeForwards
transition.duration = 0.6
transition.subtype = kCATransitionFromBottom
    
tableView.layer.add(transition, forKey: "UITableViewReloadDataAnimationKey")

Свифт 5

tableView.reloadData()
let transition = CATransition()
transition.type = .push
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
transition.fillMode = .forwards
transition.duration = 0.6
transition.subtype = .fromBottom
person kubacizek    schedule 31.01.2018

Или это:

    NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [self numberOfSectionsInTableView: self.tableView])];
    [self.tableView reloadSections: sections withRowAnimation: UITableViewRowAnimationTop];

Лично я думаю, что UITableViewRowAnimationFade выглядит намного лучше.

person Simon Tillson    schedule 06.03.2017

Это расширение UITableView работает для Swift 4:

extension UITableView {
  func reloadDataWithAnimation(duration: TimeInterval, options: UIViewAnimationOptions) {
    UIView.animate(withDuration: duration, delay: 0.0, options: options, animations: { self.alpha = 0 }, completion: nil)
    self.reloadData()
    UIView.animate(withDuration: duration, delay: 0.0, options: options, animations: { self.alpha = 1 }, completion: nil)
  }
}

Использование:

tableView.reloadDataWithAnimation(duration: 1.0, options: .curveLinear)
person fivewood    schedule 13.01.2018
comment
В этом подходе используется reloadData(), что позволяет анимировать обновления структуры tableView (не только вставки, удаления или обновления строк или разделов, но также повторную выборку или иное изменение источника данных). - person fivewood; 13.01.2018