Search code examples
iosobjective-cuitableviewnsuserdefaultsdidselectrowatindexpath

Can't get saved checkmarks to appear on UITableView


I have a UITableView where a user can tap on a cell and a checkmark appears on the cell accessory view. When the cell is tapped, the index path is saved to an array and the array is saved to disk.

When I leave and go back into the view controller, I am unable to have the checkmarks reappear on the UITableView.

- (void)viewWillAppear:(BOOL)animated {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSData *data = [defaults objectForKey:@"selectedCells"];
    self.retrievedIndexPaths = [[NSArray alloc] initWithObjects:    

    [NSKeyedUnarchiver unarchiveObjectWithData:data], nil];

    NSLog(@"%@", self.retrievedIndexPaths);

}

Probably where I'm doing something wrong:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    cell.textLabel.text = self.categoriesArray[indexPath.row];
    cell.backgroundColor = [UIColor clearColor];
    cell.textLabel.textColor = [UIColor whiteColor];

    for (NSIndexPath *retrievedIndexPath in self.retrievedIndexPaths)
    {
        if (retrievedIndexPath == indexPath)
        {   // Never hits here
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

return cell;

}

Save checkmark data:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.accessoryType == UITableViewCellAccessoryNone)
{
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    [self.selectedRowsArray addObject:cell.textLabel.text];
    self.lastIndexPath = indexPath;
    [self.selectedIndexPathsMutableArray addObject:self.lastIndexPath];

}
else
{
    cell.accessoryType = UITableViewCellAccessoryNone;
    [self.selectedRowsArray removeObject:cell.textLabel.text];
    [self.selectedIndexPathsMutableArray removeObject:indexPath];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];

NSLog(@"%@", self.selectedRowsArray);
NSLog(@"%@", self.selectedIndexPathsMutableArray);
}

#pragma mark - UIBUTTON

- (IBAction)doneButton:(UIBarButtonItem *)sender
{
    NSLog(@"button pressed");

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:self.selectedIndexPathsMutableArray] forKey:@"selectedCells"];
    [defaults synchronize];


    [[PFUser currentUser] setObject:self.selectedRowsArray forKey:@"interests"];
    [[PFUser currentUser] saveInBackground];
}

Solution

  • An indexPath his an object, so you shouldn't test for equality with "==". There's also no need to loop through the array, just use containsObject,

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
        cell.textLabel.text = self.categoriesArray[indexPath.row];
        cell.backgroundColor = [UIColor clearColor];
        cell.textLabel.textColor = [UIColor whiteColor];
    
        if ([self.retrievedIndexPaths containsObject:indexPath]){ 
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }else{
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
        return cell;
    
    }