PDA

View Full Version : How to save a checkmark in table view using NSUserDefaults




Schnigges
May 3, 2011, 03:07 PM
Hi,

how is it possible to save a checkmark in a table view?
I think the viewWillAppear method is the right place to to so, but i cannot figure it out.
Would be nice if someone could help me with that.
Here's the code i have written so far...in the .h file the currently selected cell and its text is saved.

#import "DetailTableViewController.h"


@implementation DetailTableViewController

@synthesize savedTime;
@synthesize savedCell;

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}

- (void)dealloc
{
[super dealloc];
}

- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
[super viewDidLoad];

wakeUpTimes = [[NSArray alloc] initWithObjects:@"8:00",@"9:00",@"10:00",nil];
}

- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
?????

[super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

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

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

// Configuring the cell
NSString *time = [wakeUpTimes objectAtIndex:indexPath.row];
cell.textLabel.text = time;
cell.accessoryType = UITableViewCellAccessoryNone;

return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// JUST ONE ITEM SHALL BE SELECTABLE
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSInteger catIndex = [wakeUpTimes indexOfObject:self.savedTime];
if (catIndex == indexPath.row) {
return;
}
NSIndexPath *oldIndexPath = [NSIndexPath indexPathForRow:catIndex inSection:0];

UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
if (newCell.accessoryType == UITableViewCellAccessoryNone) {
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
self.savedTime = [wakeUpTimes objectAtIndex:indexPath.row];
self.savedCell.textLabel.text = self.savedTime;

NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
[userPreferences setObject:self.savedTime forKey:@"savedTime"];
}

UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:oldIndexPath];
if (oldCell.accessoryType == UITableViewCellAccessoryCheckmark) {
oldCell.accessoryType = UITableViewCellAccessoryNone;
}
}

@end



PhoneyDeveloper
May 3, 2011, 03:24 PM
The place to restore the checkmark is cellForRowAtIndexPath. Something like

if (indexPath.row == self.selectedRowIndex)
// set the checkmark
else
// make sure the checkmark isn't visible

ulbador
May 3, 2011, 03:26 PM
Think a little bit about the problem. Basically, when someone checks a row, you have to store that fact as data somewhere. In your case, the logical place is to store it in the object that you use to build the table row.

The longer answer is this:

You have to do it when you "build" your table in "cellForRowAtIndexPath". This method gets called however many times based on the numberOfSections/numberOfRows returns when the reloadData method of the table object is executed.

This line would have to change:

cell.accessoryType = UITableViewCellAccessoryNone;

When someone checks the row, you would have to somehow store that checked state in your "wakeUpTimes" object in the appropriate spot. Then, when the table is reloaded, you would check that state, and if it's checked, set the accessoryType to be the checkmark for that row.

Schnigges
May 3, 2011, 03:44 PM
Thanks for the quick reply, works great now :)

For everyone interested in the code :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

// Configuring the cell
NSString *time = [wakeUpTimes objectAtIndex:indexPath.row];
cell.textLabel.text = time;

NSString *_savedTime = [[NSUserDefaults standardUserDefaults] stringForKey:@"savedTime"];
if([time compare:_savedTime]) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}

return cell;
}