I have a Uitableview which has Accessory type set as "CheckMark" if the cell is selected (Checked) I want to add the contents of the cell to an array and if it is unchecked I want to remove the same from the array.
I have added this code in tableView:didSelectRowAtIndexPath::
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
NSIndexPath *tableSelection = [listingSet indexPathForSelectedRow];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
[listingSet deselectRowAtIndexPath:tableSelection animated:YES];
}
else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
ID = [NSString stringWithFormat:#"%#",[[ParsedData valueForKey:#"ID"]objectAtIndex:indexPath.row]];
NSLog(#"++++++IDSSS %#",ID);
NSString *titlename = [NSString stringWithFormat:#"%#.%#",[[ParsedData valueForKey:#"UserFileName"]objectAtIndex:indexPath.row],[[ParsedData valueForKey:#"fileExtension"]objectAtIndex:indexPath.row]];
[Selectedfiles addObject:ID];
[Selectedfiles retain];
NSLog(#"++++++Titlesss %#",Selectedfiles);
[listingSet deselectRowAtIndexPath:tableSelection animated:YES];
}
}
In tableView:didSelectRowAtIndexPath::
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
NSIndexPath *tableSelection = [listingSet indexPathForSelectedRow];
ID = [NSString stringWithFormat:#"%#",[[ParsedData valueForKey:#"ID"]objectAtIndex:indexPath.row]];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
// Remove id
[Selectedfiles removeObject:ID];
cell.accessoryType = UITableViewCellAccessoryNone;
[listingSet deselectRowAtIndexPath:tableSelection animated:YES];
}
else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
// Add id
[Selectedfiles addObject:ID];
NSLog(#"++++++IDSSS %#",ID);
NSString *titlename = [NSString stringWithFormat:#"%#.%#",[[ParsedData valueForKey:#"UserFileName"]objectAtIndex:indexPath.row],[[ParsedData valueForKey:#"fileExtension"]objectAtIndex:indexPath.row]];
NSLog(#"++++++Titlesss %#",Selectedfiles);
[listingSet deselectRowAtIndexPath:tableSelection animated:YES];
}
}
Related
When i scroll Table, checkmark is hide. I know because of Reusing Cell, but I dont know how to fix. Pls help me. Here is my code:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
StudentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[StudentTableViewCell alloc] init];
}
if (_btnCancel.hidden == NO) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
I change check and uncheck in didSelectRowAtIndexPath:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cellCheck = [tableView cellForRowAtIndexPath:indexPath];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
if (_btnCancel.hidden == NO) {
if (cellCheck.accessoryType == UITableViewCellAccessoryNone) {
cellCheck.accessoryType = UITableViewCellAccessoryCheckmark;
TeacherInfo *courseStudent = studentQuitArray[indexPath.row];
[dict setObject:courseStudent.id_user forKey:#"student_id"];
[studentDetail addObject:dict];
} else {
cellCheck.accessoryType = UITableViewCellAccessoryNone;
[studentDetail removeObject: studentQuitArray[indexPath.row]];
}
}
}
When you scroll table view, cellForRowAtIndexPath for particular cell will be called in which your are setting the accessoryType as None. Instead try like below.
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
StudentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[StudentTableViewCell alloc] init];
}
if (_btnCancel.hidden == NO) {
TeacherInfo *courseStudent = studentQuitArray[indexPath.row];
if ([studentDetail containsObject:courseStudent]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
} else {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
didSelectRowAtIndexPath:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cellCheck = [tableView cellForRowAtIndexPath:indexPath];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
if (_btnCancel.hidden == NO) {
if (cellCheck.accessoryType == UITableViewCellAccessoryNone) {
cellCheck.accessoryType = UITableViewCellAccessoryCheckmark;
TeacherInfo *courseStudent = studentQuitArray[indexPath.row];
[dict setObject:courseStudent.id_user forKey:#"student_id"];
[studentDetail addObject:dict];
} else {
cellCheck.accessoryType = UITableViewCellAccessoryNone;
[studentDetail removeObject: studentQuitArray[indexPath.row]];
}
}
}
Hope this will help.
If you are reusing cells then you need to save the state of each cell .Because every time you scroll up and down, TableView will bring back the previous cell that outside of the screen.
You can save selectable state in an array and read its index in cellForRowAtIndexpath to get the current state of the cell.
You can also do this by adding one boolean property like is-selected in your "TeacherInfo" NSObject class,and set true false based on table-row selection.
Try this :
You need to add instance object of TeacherInfo instead of student id because your containedObject of array gives wrong result .
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
StudentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[StudentTableViewCell alloc] init];
}
if (_btnCancel.hidden == NO) {
TeacherInfo *courseStudent = studentQuitArray[indexPath.row];
if ([studentDetail containsObject:courseStudent]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
} else {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
didSelectRowAtIndexPath:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cellCheck = [tableView cellForRowAtIndexPath:indexPath];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
if (_btnCancel.hidden == NO) {
if (cellCheck.accessoryType == UITableViewCellAccessoryNone) {
cellCheck.accessoryType = UITableViewCellAccessoryCheckmark;
TeacherInfo *courseStudent = studentQuitArray[indexPath.row];
[studentDetail addObject:courseStudent];
} else {
cellCheck.accessoryType = UITableViewCellAccessoryNone;
[studentDetail removeObject: studentQuitArray[indexPath.row]];
}
}
}
I have a table view which list countries and I can select multiple raws. I've the option of select and deselect raws. The problem comes when I add a Search bar, I can`t deselect a raw of the results list because the method "didDeselectRowAtIndexPath" is never called when I press a results item.
I searched about this problem but nothing,
Thanks in advance,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
//[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:indexPath.row];
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryView.hidden = NO;
tableViewCell.accessoryType = UITableViewCellAccessoryCheckmark;
NSDictionary *country = [self.searchResult objectAtIndex:indexPath.row];
[self.selectedItems addObject: country];
}
else
{
//[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:indexPath.row];
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryView.hidden = NO;
tableViewCell.accessoryType = UITableViewCellAccessoryCheckmark;
NSDictionary *country = [self.countriesArray objectAtIndex:indexPath.row];
[self.selectedItems addObject: country];
}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
//[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryView.hidden = YES;
tableViewCell.accessoryType = UITableViewCellAccessoryNone;
NSDictionary *country = [self.searchResult objectAtIndex:indexPath.row];
[self.selectedItems removeObject:country];
}else
{
//[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryView.hidden = YES;
tableViewCell.accessoryType = UITableViewCellAccessoryNone;
NSDictionary *country = [self.countriesArray objectAtIndex:indexPath.row];
[self.selectedItems removeObject:country];
}
}
All,
I have a tableview that users tick their city and then the accessory shows and then I store that city as a NSUSerDefault. What is the best way so if they need to change their city again, there last one is still ticked ?
heres my code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.text = [alllocationsCity objectAtIndex:indexPath.row];
cell.accessoryType = (indexPath.row == selectedRow)?UITableViewCellAccessoryCheckmark:UITableViewCellAccessoryNone;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.CityTableView deselectRowAtIndexPath:indexPath animated:YES];
[self.CityTableView setTintColor:[UIColor grayColor]];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[self.CityTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
[[NSUserDefaults standardUserDefaults] setObject:alllocationsCity[indexPath.row] forKey:#"CitySelected"];
selectedRow = indexPath.row;
[tableView reloadData];
}
Better u can keep one mutable array which holds all the selected city names and save that to defaults for example
read the coments
- (void)viewDidLoad
{
[super viewDidLoad];
_cities = [[NSMutableArray alloc]initWithObjects:#"city1",#"city2",#"city3",#"city4", nil];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; //initially get all the selected cities
selecedArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:#"SEL_CITIES"]]; //store them in an mutable array
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.textLabel.text = [_cities objectAtIndex:indexPath.row];
cell.accessoryType = ([selecedArray containsObject:[_cities objectAtIndex:indexPath.row]]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; //set the checkmark based on weather the city name is present or not
return cell;
}
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
//update the array based on selection
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
if([selecedArray containsObject:[_cities objectAtIndex:indexPath.row]])
{
[selecedArray removeObject:[_cities objectAtIndex:indexPath.row]];
}
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selecedArray addObject:[_cities objectAtIndex:indexPath.row]];
}
//update the defaults each time for selection or deselection
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:selecedArray forKey:#"SEL_CITIES"];
[defaults synchronize];
}
hope this helps u ...
Why the UITableViewCells don't reload the checkmarks after selecting, scrolling away, then scrolling back?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
#define CHECK_NULL_STRING(str) ([str isKindOfClass:[NSNull class]] || !str)?#"":str
static NSString *CellIdentifier = #"inviteCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.textLabel.highlightedTextColor = [UIColor colorWithHexString:#"#669900"];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.backgroundColor = [UIColor blackColor];
cell.textLabel.textColor = [UIColor whiteColor];
[[UITableViewCell appearance] setTintColor:[UIColor colorWithHexString:#"#669900"]];
if (cell == nil) {
cell = [[UITableViewCell alloc] init];
}
if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; }
BOOL isSearching = tableView != self.tableView;
NSArray *arrayToUse = (isSearching ? searchResults : contactsObjects);
id p = arrayToUse[indexPath.row];
NSString *fName = (__bridge_transfer NSString *)(ABRecordCopyValue((__bridge ABRecordRef)(p), kABPersonSortByFirstName));
NSString *lName = (__bridge_transfer NSString *)(ABRecordCopyValue((__bridge ABRecordRef)(p), kABPersonSortByLastName));
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", CHECK_NULL_STRING(fName), CHECK_NULL_STRING(lName)];
BOOL showCheckmark = [[stateArray objectAtIndex:indexPath.row] boolValue];
if (showCheckmark == YES)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSLog(#"It hit showCheckmark = YES, and stateArray is %#",stateArray[indexPath.row]);
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
NSLog(#"It hit showCheckmark = NO, and stateArray is %#",stateArray[indexPath.row]);
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
id object = contactsObjects[indexPath.row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[stateArray insertObject:[NSNumber numberWithBool:YES] atIndex:indexPath.row];
[selectedObjects addObject:object];
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
[stateArray insertObject:[NSNumber numberWithBool:NO] atIndex:indexPath.row];
[selectedObjects removeObject:object];
}
//slow-motion selection animation.
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
You missed out the ! (inverse operator) on the following line meaning that the state will always be the same.
[stateArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:[[stateArray objectAtIndex:indexPath.row] boolValue]]];
It should be
[stateArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:![[stateArray objectAtIndex:indexPath.row] boolValue]]];
Edit --- I've refactored both methods because it can be done with a lot less code and it will completely simplify the methods for you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"inviteCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
BOOL isSearching = tableView != self.tableView;
NSArray *arrayToUse = (isSearching ? searchResults : contactsObjects);
id p = arrayToUse[indexPath.row];
NSString *fName = (__bridge_transfer NSString *)(ABRecordCopyValue((__bridge ABRecordRef)(p), kABPersonSortByFirstName));
NSString *lName = (__bridge_transfer NSString *)(ABRecordCopyValue((__bridge ABRecordRef)(p), kABPersonSortByLastName));
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", CHECK_NULL_STRING(fName), CHECK_NULL_STRING(lName)];
BOOL showCheckmark = [stateArray[indexPath.row] boolValue];
if (showCheckmark == YES) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
id object = contactsObjects[indexPath.row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selectedObjects addObject:object];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[selectedObjects removeObject:object];
}
stateArray[indexPath.row] = #(cell.accessoryType == UITableViewCellAccessoryCheckmark);
}
I suggest a more object oriented approach. This will ensure that your code is flexible and displays correctly all the time.
For each item you wish to display in your table, have a corresponding object. You mentioned that you are displaying contacts, so let's suppose your object is called "Contact":
//Contact.h
#interface Contact : NSObject
#property BOOL selected;
#property NSString *name;
#end
//Contact.m
#import Contact.h
#implementation Contact
+ (id) contactWithName:(NSString*)name {
Contact *nContact = [Contact new];
nContact.name = name;
nContact.selected = NO;
return nContact;
}
#end
Then, just make your view work something like this:
//ContactView.m
#interface ContactView()
#property NSMutableArray *contacts;
#end
#implementation ContactView
#synthesize contacts;
- (void) viewDidLoad {
[super viewDidLoad];
//get your contact list here. When creating contacts, be sure to assign their selected and their name as you require.
contacts = #[[Contact contactWithName:#"John"], [Contact contactWithName:#"Jane"]];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"inviteCell";
UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
Contact *cellContact = [contacts objectAtIndex:indexPath.row];
cell.textLabel.text = cellContact.name;
cell.accessoryType = cellContact.selected == YES ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Contact *cellContact = [contacts objectAtIndex:indexPath.row];
cellContact.selected = !cellContact.selected;
[contacts replaceObjectAtIndex:indexPath.row withObject:cellContact];
[tableView reloadData]; //to refresh without animation
//[tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [tableView numberOfSections])] withRowAnimation:UITableViewRowAnimationTop]; //to refresh with animation
}
#end
And boom, easy to use tables that always look right, queue properly, and are object oriented for easy maintenance later.
The cell selection problem was not solved, even when insertObject was replaced with replaceWithObject, however, one should not waste time setting BOOL objects with an NSInteger inside an NSMutableArray. Instead, for cell selection memory, one should use NSDictionary like this:
#property (nonatomic, strong) NSMutableDictionary * selectedRowCollection;
- (void)viewDidLoad{
self.selectedRowCollection = [[NSMutableDictionary alloc] init];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
id object = contactsObjects[indexPath.row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.selectedRowCollection setObject:#"1" forKey:[NSString stringWithFormat:#"%d",indexPath.row]];
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
[self.selectedRowCollection removeObjectForKey:[NSString stringWithFormat:#"%d",indexPath.row]];
}
//slow-motion selection animation.
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BOOL showCheckmark = [[self.selectedRowCollection valueForKey:[NSString stringWithFormat:#"%d",indexPath.row]] boolValue];
if (showCheckmark == YES)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
You are not doing this UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
Allocating is necessary if cell is nil. Or it cause problem while scrolling.
i have a question regarding NSUserDefaults. I am trying to save the checkmark that i place on a cell and then retrieve it when the app crashes or when user closes app and so on. I tried to use this post post as a guide, but no luck, but here's what i have so far. The code from the post works, however, i only need one checkmark to be saved rather than many. How would i achieve this?
#implementation ClientsViewController
#synthesize clientsInt; // This is just a variable that helps me do the drill down part of the rootviewcontroller
#synthesize checkedIndexPath;
- (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];
}
- (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];
if([self getCheckedForIndex:indexPath.row]==YES)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
// Configure the cell...
if (clientsInt == 0) {
cell.textLabel.text = [array1 objectAtIndex:indexPath.row];
}
else if (clientsInt == 1) {
cell.textLabel.text = [array2 objectAtIndex:indexPath.row];
}
else if (clientsInt == 2) {
cell.textLabel.text = [array3 objectAtIndex:indexPath.row];
}
else if (clientsInt == 3) {
cell.textLabel.text = [array4 objectAtIndex:indexPath.row];
}
if([self.checkedIndexPath isEqual:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Uncheck the previous checked row
if(self.checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView cellForRowAtIndexPath:self.checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
[self checkedCellAtIndex:indexPath.row];
if([self getCheckedForIndex:indexPath.row]==YES)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Maybe try something like this every time the user checks a row:
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:index] forKey:#"kCheckedBoxKey"];
Since each time, you would save the index under the same key (#"kCheckedBoxKey"), only one index will ever be stored, and it will always be the latest one that the user checked. All you would need to do the next time you load is ask userDefaults if it can find a value for the key #"kCheckedBoxKey", and if so, you would respond by programatically checking the index that was stored.
(you'd of course also want to clean it up by using #define CHECKED_KEY #"kCheckedBoxKey" at the top of the file, and use CHECKED_KEY instead of the literal string to protect against misspellings. At any rate, the point is to make sure you always save & restore using that same key.)
I recently had to save the state of each cell in my table view when the user selected or deselected them to add or remove checkmarks. Here is the snippet of code I used to save to a .plist file (let me know if you need the whole implementation I came up with:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *contentForThisRow = [[self list] objectAtIndex:[indexPath row]];
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d%d", indexPath.section, indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *documentDirectory = [(AppDelegate *)[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory];
NSString *PlistPath = [documentDirectory stringByAppendingPathComponent:#"Settings.plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:PlistPath];
NSString *row = [NSString stringWithFormat:#"%d",indexPath.row];
if([[dict objectForKey:row]isEqualToString:#"0"])
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
[[cell textLabel] setText:contentForThisRow];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *documentDirectory = [(AppDelegate *)[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory];
NSString *PlistPath = [documentDirectory stringByAppendingPathComponent:#"Settings.plist"];
NSMutableDictionary *plist = [NSMutableDictionary dictionaryWithContentsOfFile:PlistPath];
UITableViewCell *cell = [self._tableView cellForRowAtIndexPath:indexPath];
NSString *row = [NSString stringWithFormat:#"%d",indexPath.row];
if(cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSString *on = #"1";
[plist setObject:on forKey:row];
[plist writeToFile:PlistPath atomically:YES];
}
else if(cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
NSString *off = #"0";
[plist setObject:off forKey:row];
[plist writeToFile:PlistPath atomically:YES];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
You only need to save the index of the selected row