J'ai un UITableView qui a deux modes. Lorsque nous basculons entre les modes, j'ai un nombre différent de sections et de cellules par section. Idéalement, cela ferait une animation sympa lorsque la table grandit ou rétrécit.
Voici le code que j'ai essayé, mais il ne fait rien:
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
[self.tableView reloadData];
[UIView commitAnimations];
Des pensées sur la façon dont je pourrais faire ça?
cocoa-touch
animation
Vertexwahn
la source
la source
_tableView.reloadSections(NSIndexSet(index: 0), withRowAnimation: .Fade)
Notamment, cependant, il ne met à jour que la section 0, qui est la première section par défaut.Vous voudrez peut-être utiliser:
Objectif c
[UIView transitionWithView: self.tableView duration: 0.35f options: UIViewAnimationOptionTransitionCrossDissolve animations: ^(void) { [self.tableView reloadData]; } completion: nil];
Rapide
UIView.transitionWithView(tableView, duration: 0.35, options: .TransitionCrossDissolve, animations: { () -> Void in self.tableView.reloadData() }, completion: nil);
Swift 3, 4 et 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
Pas de soucis. :RÉ
Vous pouvez également utiliser n'importe lequel des
UIViewAnimationOptionTransitions
effets que vous souhaitez pour des effets plus cool:transitionNone
transitionFlipFromLeft
transitionFlipFromRight
transitionCurlUp
transitionCurlDown
transitionCrossDissolve
transitionFlipFromTop
transitionFlipFromBottom
la source
[_tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)] withRowAnimation:UITableViewRowAnimationFade];
Ayez plus de liberté en utilisant la
CATransition
classe.Il ne se limite pas à la décoloration, mais peut également faire des mouvements.
Par exemple:
(n'oubliez pas d'importer
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"];
Modifiez le
type
pour correspondre à vos besoins, par exemple,kCATransitionFade
etc.Implémentation dans 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()
Référence pour 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()
la source
layer
propriété d'unUITableViewCell
.Je pense que vous pouvez simplement mettre à jour votre structure de données, puis:
[tableView beginUpdates]; [tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]; [tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]; [tableView endUpdates];
De plus, "withRowAnimation" n'est pas exactement un booléen, mais un style d'animation:
UITableViewRowAnimationFade, UITableViewRowAnimationRight, UITableViewRowAnimationLeft, UITableViewRowAnimationTop, UITableViewRowAnimationBottom, UITableViewRowAnimationNone, UITableViewRowAnimationMiddle
la source
Toutes ces réponses supposent que vous utilisez un UITableView avec seulement 1 section.
Pour gérer avec précision les situations où vous avez plus d'une section, utilisez:
NSRange range = NSMakeRange(0, myTableView.numberOfSections); NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range]; [myTableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
(Remarque: vous devez vous assurer que vous avez plus de 0 sections!)
Une autre chose à noter est que vous pouvez rencontrer une NSInternalInconsistencyException si vous essayez de mettre à jour simultanément votre source de données avec ce code. Si tel est le cas, vous pouvez utiliser une logique similaire à celle-ci:
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];
la source
La façon d'aborder cela est de dire à tableView de supprimer et d'ajouter des lignes et des sections avec
insertRowsAtIndexPaths:withRowAnimation:
,deleteRowsAtIndexPaths:withRowAnimation:
,insertSections:withRowAnimation:
EtdeleteSections:withRowAnimation:
méthodes de UITableView.
Lorsque vous appelez ces méthodes, la table animera dans / hors les éléments que vous avez demandés, puis appellera reloadData sur elle-même afin que vous puissiez mettre à jour l'état après cette animation. Cette partie est importante - si vous animez tout mais ne modifiez pas les données renvoyées par la source de données de la table, les lignes réapparaîtront une fois l'animation terminée.
Ainsi, votre flux d'application serait:
[self setTableIsInSecondState:YES];
[myTable deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]];
Tant que les méthodes dataSource de votre table retournent le nouvel ensemble correct de sections et de lignes en cochant
[self tableIsInSecondState]
(ou quoi que ce soit), cela produira l'effet que vous recherchez.la source
Je ne peux pas commenter la réponse principale, mais une mise en œuvre rapide serait:
self.tableView.reloadSections([0], with: UITableViewRowAnimation.fade)
vous pouvez inclure autant de sections que vous souhaitez mettre à jour dans le premier argument de reloadSections.
Autres animations disponibles dans la documentation: https://developer.apple.com/reference/uikit/uitableviewrowanimation
fondu La ou les lignes insérées ou supprimées s'affichent dans ou hors de la vue tableau.
right La ou les lignes insérées glissent à partir de la droite; la ou les lignes supprimées glissent vers la droite.
gauche La ou les lignes insérées glissent à partir de la gauche; la ou les lignes supprimées glissent vers la gauche.
top La ou les lignes insérées glissent depuis le haut; la ou les lignes supprimées glissent vers le haut.
bas La ou les lignes insérées glissent depuis le bas; la ou les lignes supprimées glissent vers le bas.
case aucun Les lignes insérées ou supprimées utilisent les animations par défaut.
middle La vue tableau tente de garder les anciennes et les nouvelles cellules centrées dans l'espace qu'elles occupaient ou occuperont. Disponible sur iPhone 3.2.
automatique La vue de table choisit un style d'animation approprié pour vous. (Introduit dans iOS 5.0.)
la source
Version Swift 4 pour la réponse @dmarnel:
tableView.reloadSections(IndexSet(integer: 0), with: .automatic)
la source
Mise en œuvre rapide:
let range = NSMakeRange(0, self.tableView!.numberOfSections()) let indexSet = NSIndexSet(indexesInRange: range) self.tableView!.reloadSections(indexSet, withRowAnimation: UITableViewRowAnimation.Automatic)
la source
Pour Swift 4
tableView.reloadSections([0], with: UITableView.RowAnimation.fade)
la source
Dans mon cas, je voulais ajouter 10 lignes supplémentaires dans la tableview (pour une fonctionnalité de type "afficher plus de résultats") et j'ai fait ce qui suit:
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];
Dans la plupart des cas, au lieu de "self.numberOfRows", vous utiliserez généralement le nombre du tableau d'objets pour la tableview. Donc, pour vous assurer que cette solution fonctionne bien pour vous, "arrayOfIndexPaths" doit être un tableau précis des chemins d'index des lignes insérées. Si la ligne existe pour l'un de ces chemins d'index, le code peut planter, vous devez donc utiliser la méthode "reloadRowsAtIndexPaths: withRowAnimation:" pour ces chemins d'index afin d'éviter de planter
la source
Si vous souhaitez ajouter vos propres animations personnalisées aux cellules UITableView, utilisez
[theTableView reloadData]; [theTableView layoutSubviews]; NSArray* visibleViews = [theTableView visibleCells];
pour obtenir un tableau de cellules visibles. Ajoutez ensuite une animation personnalisée à chaque cellule.
Découvrez ce que j'ai publié pour une animation de cellule personnalisée fluide. https://gist.github.com/floprr/1b7a58e4a18449d962bd
la source
L'animation sans reloadData () dans Swift peut être effectuée comme ceci (à partir de la version 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()
au cas où vous auriez besoin d'appeler reloadData () après la fin de l'animation, vous pouvez accepter les changements dans CATransaction comme ceci:
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()
La logique est affichée pour le cas où vous supprimez des lignes, mais la même idée fonctionne également pour l'ajout de lignes. Vous pouvez également modifier l'animation en UITableViewRowAnimation.Left pour la rendre nette, ou choisir dans la liste des autres animations disponibles.
la source
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];
la source
.3
deux fois?Pour recharger toutes les sections , pas seulement une avec une durée personnalisée .
duration
Paramètre utilisateur deUIView.animate
pour définir la durée personnalisée.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) })
la source
UITableView
Animations natives dans SwiftInsérez et supprimez des lignes en même temps avec
tableView.performBatchUpdates
pour qu'elles se produisent simultanément. En vous appuyant sur la réponse de @iKenndac, utilisez des méthodes telles que:tableView.insertSections
tableView.insertRows
tableView.deleteSections
tableView.deleteRows
Ex:
tableView.performBatchUpdates({ tableView.insertSections([0], with: .top) })
Cela insère une section à la position zéro avec une animation qui se charge du haut. Cela réexécutera le
cellForRowAt
méthode et recherchera une nouvelle cellule à cette position. Vous pouvez recharger la vue de table entière de cette façon avec des animations spécifiques.Re: la question OP, un drapeau conditionnel aurait été nécessaire pour afficher les cellules pour l'état de vue de table alternatif.
la source