Вопрос:

Имейте reloadData для анимации UITableView при изменении

cocoa-touch animation

118983 просмотра

14 ответа

0 Репутация автора

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

Вот код, который я пробовал, но он ничего не делает:

CGContextRef context = UIGraphicsGetCurrentContext(); 
[UIView beginAnimations:nil context:context]; 
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
[UIView setAnimationDuration:0.5]; 

[self.tableView reloadData];
[UIView commitAnimations];

Любые мысли о том, как я могу это сделать?

Автор: Chris Butler Источник Размещён: 07.01.2009 07:25

Ответы (14)


17 плюса

17983 Репутация автора

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

insertRowsAtIndexPaths:withRowAnimation:, deleteRowsAtIndexPaths:withRowAnimation:, insertSections:withRowAnimation:И deleteSections:withRowAnimation:

методы UITableView. Когда вы вызываете эти методы, таблица будет анимировать в / из запрошенных вами элементов, а затем вызвать reloadData сама по себе, чтобы вы могли обновить состояние после этой анимации. Эта часть важна - если вы окунаете все, но не меняете данные, возвращаемые данным DataSource таблицы, строки появятся снова после завершения анимации.

Таким образом, ваш поток приложений будет:

[self setTableIsInSecondState:YES];

[myTable deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]];

Пока методы dataSource в вашей таблице возвращают правильный новый набор разделов и строк, проверяя [self tableIsInSecondState](или что-то еще), это обеспечит эффект, который вы ищете.

Автор: iKenndac Размещён: 07.01.2009 05:02

59 плюса

1517 Репутация автора

Я считаю, что вы можете просто обновить свою структуру данных, а затем:

[tableView beginUpdates];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES];
[tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES];
[tableView endUpdates];

Кроме того, «withRowAnimation» не является булевым, а анимационным стилем:

UITableViewRowAnimationFade,
UITableViewRowAnimationRight,
UITableViewRowAnimationLeft,
UITableViewRowAnimationTop,
UITableViewRowAnimationBottom,
UITableViewRowAnimationNone,
UITableViewRowAnimationMiddle
Автор: Tiago Fael Matos Размещён: 29.04.2010 03:53

381 плюса

3968 Репутация автора

На самом деле, это очень просто:

[_tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];

Из документации :

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

Автор: dmarnel Размещён: 23.09.2011 12:24

23 плюса

3142 Репутация автора

Все эти ответы предполагают, что вы используете UITableView только с 1 секцией.

Чтобы точно обрабатывать ситуации, когда у вас более 1 раздела, используйте:

NSRange range = NSMakeRange(0, myTableView.numberOfSections);
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
[myTableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

(Примечание: вы должны убедиться, что у вас более 0 секций!)

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

int sectionNumber = 0; //Note that your section may be different

int nextIndex = [currentItems count]; //starting index of newly added items

[myTableView beginUpdates];

for (NSObject *item in itemsToAdd) {
    //Add the item to the data source
    [currentItems addObject:item];

    //Add the item to the table view
    NSIndexPath *path = [NSIndexPath indexPathForRow:nextIndex++ inSection:sectionNumber];
    [myTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationAutomatic];
}

[myTableView endUpdates];
Автор: diadyne Размещён: 20.03.2012 02:32

222 плюса

2819 Репутация автора

Вы можете использовать:

Objective-C

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

стриж

UIView.transitionWithView(tableView,
                          duration: 0.35,
                          options: .TransitionCrossDissolve,
                          animations:
{ () -> Void in
    self.tableView.reloadData()
},
                          completion: nil);

Swift 3

UIView.transition(with: tableView,
                  duration: 0.35,
                  options: .transitionCrossDissolve,
                  animations: { self.tableView.reloadData() }) // left out the unnecessary syntax in the completion block and the optional completion parameter

Никаких неприятностей. : D

Вы также можете использовать любой из них UIViewAnimationOptionTransitionsдля более холодных эффектов:

  • TransitionNone
  • TransitionFlipFromLeft
  • TransitionFlipFromRight
  • TransitionCurlUp
  • TransitionCurlDown
  • TransitionCrossDissolve
  • TransitionFlipFromTop
  • TransitionFlipFromBottom
Автор: Kenn Cal Размещён: 07.11.2012 12:45

64 плюса

6592 Репутация автора

Имейте больше свободы, используя CATransitionкласс.

Он не ограничивается выцветанием, но может также делать движения.


Например:

(не забудьте импортировать QuartzCore)

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

[[self.tableView layer] addAnimation:transition forKey:@"UITableViewReloadDataAnimationKey"];

Измените в typeсоответствии с вашими потребностями, например, и kCATransitionFadeт. Д.

Внедрение в Swift:

let transition = CATransition()
transition.type = kCATransitionPush
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.fillMode = kCAFillModeForwards
transition.duration = 0.5
transition.subtype = kCATransitionFromTop
self.tableView.layer.addAnimation(transition, forKey: "UITableViewReloadDataAnimationKey")
// Update your data source here
self.tableView.reloadData()

Справочная информация для CATransition

Автор: code ninja Размещён: 10.03.2013 10:03

9 плюса

6457 Репутация автора

Быстрая реализация:

let range = NSMakeRange(0, self.tableView!.numberOfSections())
let indexSet = NSIndexSet(indexesInRange: range)
self.tableView!.reloadSections(indexSet, withRowAnimation: UITableViewRowAnimation.Automatic)
Автор: Michael Peterson Размещён: 01.08.2014 07:51

1 плюс

677 Репутация автора

В моем случае я хотел добавить еще 10 строк в tableview (для функции «показать больше результатов»), и я сделал следующее:

  NSInteger tempNumber = self.numberOfRows;
  self.numberOfRows += 10;
  NSMutableArray *arrayOfIndexPaths = [[NSMutableArray alloc] init];
  for (NSInteger i = tempNumber; i < self.numberOfRows; i++) {
    [arrayOfIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
  }
  [self.tableView beginUpdates];
  [self.tableView insertRowsAtIndexPaths:arrayOfIndexPaths withRowAnimation:UITableViewRowAnimationTop];
  [self.tableView endUpdates];

В большинстве случаев вместо «self.numberOfRows» вы обычно используете подсчет массива объектов для представления таблицы. Поэтому, чтобы убедиться, что это решение работает хорошо для вас, «arrayOfIndexPaths» должен быть точным массивом путей указателей вставляемых строк. Если строка существует для любого из этих указательных путей, код может упасть, поэтому вы должны использовать метод «reloadRowsAtIndexPaths: withRowAnimation:» для этих указательных путей, чтобы избежать сбоев

Автор: Lucas Chwe Размещён: 17.04.2015 06:52

1 плюс

370 Репутация автора

Если вы хотите добавить свои собственные анимации в ячейки UITableView, используйте

[theTableView reloadData];
[theTableView layoutSubviews];
NSArray* visibleViews = [theTableView visibleCells];

для получения массива видимых ячеек. Затем добавьте произвольную анимацию в каждую ячейку.

Проверьте этот смысл, который я опубликовал для гладкой пользовательской анимации ячеек. https://gist.github.com/floprr/1b7a58e4a18449d962bd

Автор: flopr Размещён: 23.06.2015 04:47

0 плюса

1 Репутация автора

CATransition *animation = [CATransition animation];
animation.duration = .3;
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setDuration:.3];

[[_elementTableView layer] addAnimation:animation forKey:@"UITableViewReloadDataAnimationKey"];

[tableView reloadData];
Автор: Mayur Sardana Размещён: 04.11.2015 07:49

1 плюс

1788 Репутация автора

Анимация без reloadData () в Swift может быть выполнена следующим образом ( начиная с версии 2.2):

tableview.beginUpdates()
var indexPathsToDeleteForAnimation: [NSIndexPath] = []
var numOfCellsToRemove = ArrayOfItemsToRemove ?? 0

// Do your work here
while numOfCellsToRemove > 0 {
    // ...or here, if you need to add/remove the same amount of objects to/from somewhere
    indexPathsToDeleteForAnimation.append(NSIndexPath(forRow: selectedCellIndex+numOfCellsToRemove, inSection: 0))
    numOfCellsToRemove -= 1
}
tableview.deleteRowsAtIndexPaths(indexPathsToDeleteForAnimation, withRowAnimation: UITableViewRowAnimation.Right)
tableview.endUpdates()

в случае, если вам нужно вызвать reloadData () после окончания анимации, вы можете принять изменения в CATransaction следующим образом:

CATransaction.begin()
CATransaction.setCompletionBlock({() in self.tableview.reloadData() })
tableview.beginUpdates()
var indexPathsToDeleteForAnimation: [NSIndexPath] = []
var numOfCellsToRemove = ArrayOfItemsToRemove.count ?? 0

// Do your work here
while numOfCellsToRemove > 0 {
     // ...or here, if you need to add/remove the same amount of objects to/from somewhere
     indexPathsToDeleteForAnimation.append(NSIndexPath(forRow: selectedCellIndex+numOfCellsToRemove, inSection: 0))
     numOfCellsToRemove -= 1
}
tableview.deleteRowsAtIndexPaths(indexPathsToDeleteForAnimation, withRowAnimation: UITableViewRowAnimation.Right)
tableview.endUpdates()
CATransaction.commit()

Логика показана для случая, когда вы удаляете строки, но эта же идея работает и для добавления строк. Вы также можете изменить анимацию на UITableViewRowAnimation.Left, чтобы сделать ее опрятной или выбрать из списка других доступных анимаций.

Автор: Vitalii Размещён: 25.05.2016 05:30

14 плюса

775 Репутация автора

Я не могу комментировать верхний ответ, но быстрая реализация:

self.tableView.reloadSections([0], with: UITableViewRowAnimation.fade)

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

Другие анимации, доступные из документов: https://developer.apple.com/reference/uikit/uitableviewrowanimation

fade Вставленные или удаленные строки или строки исчезают в виде таблицы или из нее.

right Вставленный ряд или строки скользят справа; удаленные строки или строки сдвигаются вправо.

left Вставленные строки или строки перемещаются слева; удаленные строки или строки сдвигаются влево.

top Вставленные строки или строки скользят сверху; удаленные строки или строки выходят вверх.

bottom Вставленные строки или ряды скользят снизу; удаленные строки или строки скользят вниз.

case none Вставленные или удаленные строки используют анимацию по умолчанию.

middle В представлении таблицы делается попытка сохранить старые и новые ячейки с центром в пространстве, которое они сделали или будут занимать. Доступен в iPhone 3.2.

автоматический Вид таблицы выбирает для вас подходящий стиль анимации. (Представлено в iOS 5.0.)

Автор: Christopher Larsen Размещён: 10.08.2016 09:24

8 плюса

4119 Репутация автора

Версия Swift 4 для ответа @dmarnel:

tableView.reloadSections(IndexSet(integer: 0), with: .automatic)
Автор: chengsam Размещён: 07.06.2018 10:42

0 плюса

2809 Репутация автора

Для Swift 4

tableView.reloadSections([0], with: UITableView.RowAnimation.fade)
Автор: Claus Размещён: 06.12.2018 10:06
Вопросы из категории :
32x32