У меня есть UITableView с двумя режимами. Когда мы переключаемся между режимами, у меня разное количество секций и ячеек на секцию. В идеале, он делал бы классную анимацию, когда таблица растет или сжимается.
Вот код, который я пробовал, но он ничего не делает:
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
[self.tableView reloadData];
[UIView commitAnimations];
Есть мысли о том, как я мог это сделать?
cocoa-touch
animation
Vertexwahn
источник
источник
_tableView.reloadSections(NSIndexSet(index: 0), withRowAnimation: .Fade)
примечательно, что она обновляет только Раздел 0, который является первым разделом по умолчанию.Вы можете использовать:
Цель-C
[UIView transitionWithView: self.tableView duration: 0.35f options: UIViewAnimationOptionTransitionCrossDissolve animations: ^(void) { [self.tableView reloadData]; } completion: nil];
Swift
UIView.transitionWithView(tableView, duration: 0.35, options: .TransitionCrossDissolve, animations: { () -> Void in self.tableView.reloadData() }, completion: nil);
Swift 3, 4 и 5
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
источник
[_tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)] withRowAnimation:UITableViewRowAnimationFade];
Получите больше свободы, используя
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
Swift 5:
let transition = CATransition() transition.type = CATransitionType.push transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) transition.fillMode = CAMediaTimingFillMode.forwards transition.duration = 0.5 transition.subtype = CATransitionSubtype.fromTop self.tableView.layer.add(transition, forKey: "UITableViewReloadDataAnimationKey") // Update your data source here self.tableView.reloadData()
источник
layer
свойствуUITableViewCell
.Я считаю, что вы можете просто обновить свою структуру данных, а затем:
[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
источник
Все эти ответы предполагают, что вы используете UITableView только с 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];
источник
Чтобы приблизиться к этому, нужно сказать tableView удалить и добавить строки и разделы с
insertRowsAtIndexPaths:withRowAnimation:
,deleteRowsAtIndexPaths:withRowAnimation:
,insertSections:withRowAnimation:
ИdeleteSections:withRowAnimation:
методы UITableView.
Когда вы вызываете эти методы, таблица будет вводить / выводить запрошенные вами элементы, а затем вызывать reloadData для себя, чтобы вы могли обновить состояние после этой анимации. Эта часть важна - если вы анимируете все, но не изменяете данные, возвращаемые источником данных таблицы, строки появятся снова после завершения анимации.
Итак, поток вашего приложения будет следующим:
[self setTableIsInSecondState:YES];
[myTable deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]];
Пока методы dataSource вашей таблицы возвращают правильный новый набор разделов и строк, проверяя
[self tableIsInSecondState]
(или что-то еще), это приведет к желаемому эффекту.источник
Я не могу прокомментировать главный ответ, но быстрая реализация была бы такой:
self.tableView.reloadSections([0], with: UITableViewRowAnimation.fade)
вы можете включить столько разделов, сколько хотите обновить, в первый аргумент для reloadSections.
Другие анимации доступны в документации: https://developer.apple.com/reference/uikit/uitableviewrowanimation
fade Вставленная или удаленная строка или строки переходят в табличное представление или исчезают из него.
вправо Вставленная строка или строки вставляются справа; удаленная строка или строки сдвинутся вправо.
слева Вставленная строка или строки вставляются слева; удаленная строка или строки сдвинутся влево.
вверх Вставленная строка или строки вставляются сверху; удаленная строка или строки выдвигаются вверх.
снизу Вставленная строка или строки сдвигаются снизу; удаленная строка или строки выдвигаются вниз.
case none Для вставленных или удаленных строк используется анимация по умолчанию.
middle В табличном представлении стараются удерживать старые и новые ячейки по центру в пространстве, которое они занимали или будут занимать. Доступно в iPhone 3.2.
автоматически В виде таблицы выбирается подходящий стиль анимации. (Представлено в iOS 5.0.)
источник
Версия Swift 4 для ответа @dmarnel:
tableView.reloadSections(IndexSet(integer: 0), with: .automatic)
источник
Быстрая реализация:
let range = NSMakeRange(0, self.tableView!.numberOfSections()) let indexSet = NSIndexSet(indexesInRange: range) self.tableView!.reloadSections(indexSet, withRowAnimation: UITableViewRowAnimation.Automatic)
источник
Для Swift 4
tableView.reloadSections([0], with: UITableView.RowAnimation.fade)
источник
В моем случае я хотел добавить еще 10 строк в табличное представление (для функциональности типа «показать больше результатов») и сделал следующее:
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: для этих путей индекса, чтобы избежать сбоя
источник
Если вы хотите добавить свои собственные анимации в ячейки UITableView, используйте
[theTableView reloadData]; [theTableView layoutSubviews]; NSArray* visibleViews = [theTableView visibleCells];
чтобы получить массив видимых ячеек. Затем добавьте любую настраиваемую анимацию в каждую ячейку.
Ознакомьтесь с этой публикацией, чтобы узнать о плавной пользовательской анимации ячеек. https://gist.github.com/floprr/1b7a58e4a18449d962bd
источник
Анимировать без 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, чтобы сделать ее аккуратной, или выбрать из списка других доступных анимаций.
источник
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];
источник
.3
дважды?Чтобы перезагрузить все разделы , а не только один с настраиваемой продолжительностью .
Пользовательский
duration
параметрUIView.animate
для установки произвольной продолжительности.UIView.animate(withDuration: 0.4, animations: { [weak self] in guard let `self` = self else { return } let indexSet = IndexSet(integersIn: 0..<self.tableView.numberOfSections) self.tableView.reloadSections(indexSet, with: UITableView.RowAnimation.fade) })
источник
Родная
UITableView
анимация в SwiftВставляйте и удаляйте все строки одновременно,
tableView.performBatchUpdates
чтобы они происходили одновременно. Основываясь на ответе @iKenndac, используйте такие методы, как:tableView.insertSections
tableView.insertRows
tableView.deleteSections
tableView.deleteRows
Пример:
tableView.performBatchUpdates({ tableView.insertSections([0], with: .top) })
Это вставит раздел в нулевую позицию с анимацией, которая загружается сверху. Это повторно запустит
cellForRowAt
метод и проверит наличие новой ячейки в этой позиции. Таким образом, вы можете перезагрузить весь вид таблицы с определенной анимацией.Re: вопрос OP, условный флаг был бы необходим для отображения ячеек для альтернативного состояния представления таблицы.
источник