web-dev-qa-db-fra.com

comment utiliser correctement insertRowsAtIndexPaths?

J'ai parcouru tous les exemples en ligne et je n'ai pas pu trouver comment ajouter correctement une cellule à une table avec animation. Disons que j'ai une section avec une cellule et je veux ajouter une autre cellule une fois que l'utilisateur clique sur l'accessoire de la première cellule.

Ma méthode "ajouter" fait ceci:

- (IBAction) toggleEnabledTextForSwitch1onSomeLabel: (id) sender {  
if (switch1.on) {

    NSArray *appleComputers = [NSArray arrayWithObjects:@"WWWWW" ,@"XXXX", @"YYYY", @"ZZZZ", nil];
    NSDictionary *appleComputersDict = [NSDictionary dictionaryWithObject:appleComputers forKey:@"Computers"];
    [listOfItems replaceObjectAtIndex:0 withObject:appleComputersDict];
    [tblSimpleTable reloadData];

}

Ce qui fonctionne mais il n'y a pas d'animation. Je comprends que pour ajouter une animation, je dois utiliser insertRowsAtIndexPaths: withRowAnimation, j'ai donc essayé des tonnes d'options mais cela se bloque toujours lors de l'exécution de la méthode insertRowsAtIndexPaths: withRowAnimation.

Mon récent essai a été en faisant ceci:

- (IBAction) toggleEnabledTextForSwitch1onSomeLabel: (id) sender {  
if (switch1.on) {

    NSIndexPath *path1 = [NSIndexPath indexPathForRow:1 inSection:0]; //ALSO TRIED WITH indexPathRow:0
      NSArray *indexArray = [NSArray arrayWithObjects:path1,nil];   
     [tblSimpleTable insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationRight];

}
}  

Qu'est-ce que je fais mal? Comment puis-je y arriver facilement? Je ne comprends pas toute cette chose indexPathForRow ... Je ne comprends pas non plus comment avec cette méthode, je peux ajouter un nom d'étiquette à la nouvelle cellule. S'il vous plaît, aidez ... merci !!

33
TommyG

La chose importante à garder à l'esprit lors de l'utilisation de insertRowsAtIndexPaths est que votre UITableViewDataSource doit correspondre à ce que l'insert lui dit de faire. Si vous ajoutez une ligne à la vue de table, assurez-vous que les données de sauvegarde sont déjà mises à jour pour correspondre.

22
Joshua Weinberg

C'est un processus en deux étapes:

Mettez d'abord à jour votre source de données afin que numberOfRowsInSection et cellForRowAtIndexPath renvoient les valeurs correctes pour vos données post-insertion. Vous devez le faire avant d'insérer ou de supprimer des lignes ou vous verrez l'erreur "nombre de lignes non valide" que vous obtenez.

Insérez ensuite votre ligne:

[tblSimpleTable beginUpdates];
[tblSimpleTable insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationRight];
[tblSimpleTable endUpdates];

L'insertion ou la suppression d'une ligne ne modifie pas votre source de données; vous devez le faire vous-même.

23
Terry Wilcox

Tout d'abord, vous devez mettre à jour votre modèle de données juste avant la mise à jour de la table elle-même. Vous pouvez également utiliser:

[tableView beginUpdates];
// do all row insertion/delete here
[tableView endUpdates];

Et la table produira tout changé à la fois avec animation (si vous le spécifiez)

6
Serhii Mamontov

Le insertRowsAtIndexPaths:withRowAnimation: ET les modifications apportées à votre modèle de données les deux doivent se produire entre les deuxbeginUpdates et endUpates

J'ai créé un exemple simple qui devrait fonctionner seul. J'ai passé une semaine à bidouiller pour essayer de comprendre cela car je n'ai trouvé aucun exemple simple, alors j'espère que cela fera gagner du temps et des maux de tête à quelqu'un!

@interface MyTableViewController ()
@property (nonatomic, strong) NSMutableArray *expandableArray;
@property (nonatomic, strong) NSMutableArray *indexPaths;
@property (nonatomic, strong) UITableView *myTableView;
@end

@implementation MyTableViewController

- (void)viewDidLoad
{
    [self setupArray];
}

- (void)setupArray
{
    self.expandableArray = @[@"One", @"Two", @"Three", @"Four", @"Five"].mutableCopy;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.expandableArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //here you should create a cell that displays information from self.expandableArray, and return it
}

//call this method if your button/cell/whatever is tapped
- (void)didTapTriggerToChangeTableView
{
    if (/*some condition occurs that makes you want to expand the tableView*/) {
        [self expandArray]
    }else if (/*some other condition occurs that makes you want to retract the tableView*/){
        [self retractArray]
    }
}

//this example adds 1 item
- (void)expandArray
{
    //create an array of indexPaths
    self.indexPaths = [[NSMutableArray alloc] init];
    for (int i = theFirstIndexWhereYouWantToInsertYourAdditionalCells; i < theTotalNumberOfAdditionalCellsToInsert + theFirstIndexWhereYouWantToInsertYourAdditionalCells; i++) {
        [self.indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
    }

    //modify your array AND call insertRowsAtIndexPaths:withRowAnimation: INBETWEEN beginUpdates and endUpdates
    [self.myTableView beginUpdates];
    //HERE IS WHERE YOU NEED TO ALTER self.expandableArray to have the additional/new data values, eg:
    [self.expandableArray addObject:@"Six"];
    [self.myTableView insertRowsAtIndexPaths:self.indexPaths withRowAnimation:(UITableViewRowAnimationFade)];  //or a rowAnimation of your choice

    [self.myTableView endUpdates];
}

//this example removes all but the first 3 items
- (void)retractArray
{
    NSRange range;
    range.location = 3;
    range.length = self.expandableArray.count - 3;

    //modify your array AND call insertRowsAtIndexPaths:withRowAnimation: INBETWEEN beginUpdates and endUpdates
    [self.myTableView beginUpdates];
    [self.expandableArray removeObjectsInRange:range];
    [self.myTableView deleteRowsAtIndexPaths:self.indexPaths withRowAnimation:UITableViewRowAnimationFade];  //or a rowAnimation of your choice
    [self.myTableView endUpdates];
}

@end
2
jungledev

Pour les utilisateurs Swift

// have inserted new item into data source

// update
self.tableView.beginUpdates()
var ip = NSIndexPath(forRow:find(self.yourDataSource, theNewObject)!, inSection: 0)
self.tableView.insertRowsAtIndexPaths([ip], withRowAnimation: UITableViewRowAnimation.Fade)
self.tableView.endUpdates()
0
DogCoffee