简体   繁体   中英

Tracking UITableViewCells

I have a to-do list app with a bunch of tasks. Each task has a UITableViewCell. After each table view cell is tapped, it creates a view controller with the task at that row's index path's property. These view controllers are all stored in a NSDictionary. This is the code representation of what I just said:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    DetailViewController *detailVC;
    if (![self.detailViewsDictionary.allKeys containsObject:indexPath]){
        detailVC = [[DetailViewController alloc]initWithNibName:@"DetailViewController" bundle:nil];
        [self.detailViewsDictionary setObject:detailVC forKey:indexPath];
        detailVC.context = self.managedObjectContext;
    }else{
        detailVC = self.detailViewsDictionary[indexPath];
    }
        Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        detailVC.testTask = task;
        [[self navigationController] pushViewController:detailVC animated:YES];
    NSLog(@"%@", self.detailViewsDictionary);
}

So this method of creating unique view controllers and storing them with a certain key almost always works. The problem arises when I delete or move the view controllers:

I was under the impression that a cell's gets recycled as you scroll down (dequeue). This means that marking each cell with a number identifier would result in multiple cells for the same identifier.

Also, if you stored each view controller with a indexPath key, how do you make sure the key isn't set to two view controllers..? For example. Let's say you have 4 cells, which means 4 view controllers. You delete cell 3. Cell 4 moves down to cell 3s spot. You create a new cell which goes to spot 4. Now you have two controllers with the same indexPath key! How do you avoid this?? It's screwing up my app right now because tasks that have already been moved are loading their properties in the wrong view controller/cell!

I was suggested this to solve the problem before: "You maintain an NSMutableArray that "shadows" the contents of the table." I was also suggested to use tags. However, I don't understand what how to implement these.

edit: ---random string--- In tasks.m

-(NSString *)uniqueIdentifierString{
    static NSString *alphabet  = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXZY0123456789";
    NSMutableString *s = [NSMutableString stringWithCapacity:20];
    for (NSUInteger i = 0U; i < 20; i++) {
        u_int32_t r = arc4random() % [alphabet length];
        unichar c = [alphabet characterAtIndex:r];
        [s appendFormat:@"%C", c];
    }
    return s;
}

In tableviewcontroller.m

   -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    DetailViewController *detailVC;
     Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    if (![self.detailViewsDictionary.allKeys containsObject:task.uniqueIdentifierString]){
        detailVC = [[DetailViewController alloc]initWithNibName:@"DetailViewController" bundle:nil];
        [self.detailViewsDictionary setObject:detailVC forKey:task.uniqueIdentifierString];
        detailVC.context = self.managedObjectContext;
    }else{
        detailVC = self.detailViewsDictionary[task.uniqueIdentifierString];
    }
        detailVC.testTask = task;
        [[self navigationController] pushViewController:detailVC animated:YES];
    NSLog(@"%@", detailVC);
    NSLog(@"%@", task.uniqueIdentifierString);
}

One solution would be to decouple your VCs from the table cells. You could store the VCs in your dictionary referenced by an ID that is unique to the task, but not worry about the table cell. If the task is moved or deleted, you can handle that elsewhere without worrying about the VC array being instantly wrong.

Your other option would be to hook into the move/edit methods the logic for iterating over the VC array to adjust the array at that time.

Given that UITableView expects cells to be reused, you can see how it isn't meant to be a storage mechanism for other data.

It would be best to decouple the data so that you aren't bound to the order or existence of them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM