How to save tableView cell's checkmark after reload view use NSUserDefaults?

Andy_24 picture Andy_24 · Aug 25, 2012 · Viewed 8.3k times · Source

I'm new to ios development, and I'm using checkmark for cells in a UITableView.

I want storing checked cell in a NSUserDefaults database, When I reload the app, the checked cell that previously selected will be display, I'm try to defferent ways, but still failed to implement it.

Anybody can help me? I would be highly appreciate it. Sorry, my english is not good.

My code is below:

#import "FirstRowSubview.h"

@interface FirstRowSubview ()

@end

@implementation FirstRowSubview

@synthesize array = _array;
@synthesize lastIndexPath = _lastIndexPath;


- (void)viewDidLoad
{
    [super viewDidLoad];
    NSMutableArray *list = [[NSMutableArray alloc] initWithObjects:@"ffgfgh", @"564654", @"56548", @"fgmjfgmf", @"ggkdj", nil];
    self.array = list;
    [list release];

}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.array = nil;
}


#pragma mark -
#pragma mark - TableView Datasource Methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_array count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *subviewCells = @"Cells";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:subviewCells];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:subviewCells];
    }
    NSUInteger oldRow = [_lastIndexPath row];
    cell.accessoryType = (indexPath.row == oldRow && _lastIndexPath != nil) ?
    UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
    cell.textLabel.text = [_array objectAtIndex:indexPath.row];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[NSNumber numberWithInt:_lastIndexPath.row] forKey:@"lastIndexPath"];
    [defaults synchronize];



    return cell;
 }

#pragma mark -
#pragma mark - TableView Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    int newRow = [indexPath row];
    int oldRow = (_lastIndexPath != nil) ? [_lastIndexPath row] : -1;

    if (newRow != oldRow) {
        UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
        newCell.accessoryType = UITableViewCellAccessoryCheckmark;

        UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:_lastIndexPath];
        oldCell.accessoryType = UITableViewCellAccessoryNone;

        [indexPath retain];
        [_lastIndexPath release];
        _lastIndexPath = indexPath;


        [tableView deselectRowAtIndexPath:indexPath animated:YES];


    }

}

Answer

Hemang picture Hemang · Aug 25, 2012

It can be easy to store and retrieve checked cell(s) information with NSUserDefaults.

NSUserDefaults can store the data interms of Key / Value pair. Here in your case value could be boolean and key could combination of NSString & indexpath.row from UITableView.

You can make a functions like,

- (NSString *)getKeyForIndex:(int)index
{
    return [NSString stringWithFormat:@"KEY%d",index];
}

- (BOOL) getCheckedForIndex:(int)index
{                     
    if([[[NSUserDefaults standardUserDefaults] valueForKey:[self getKeyForIndex:index]] boolValue]==YES) 
    { 
        return YES;
    }
    else 
    { 
        return NO; 
    }
}

- (void) checkedCellAtIndex:(int)index
{
    BOOL boolChecked = [self getCheckedForIndex:index];

    [[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:!boolChecked] forKey:[self getKeyForIndex:index]];
    [[NSUserDefaults standardUserDefaults] synchronize];
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_array count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //Here, you can check for previously checked cells like

    static NSString *subviewCells = @"Cells";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:subviewCells];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:subviewCells];
    }

    cell.textLabel.text = [_array objectAtIndex:indexPath.row];

    if([self getCheckedForIndex:indexPath.row]==YES)
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else
    {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    //Use checkedCellAtIndex for check or uncheck cell
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    [self checkedCellAtIndex:indexPath.row];

    if([self getCheckedForIndex:indexPath.row]==YES)
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else
    {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
}

P.S. Please, note that, this method will only useful and suggested if order of data from your NSArray will always in same order. Other then NSUserDefaults you've options like SQLite Database or plist file or any other option! Thanks :)