How to Save Tableview Cell's Checkmark After Reload View Use Nsuserdefaults

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

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 :)

Save & Retrieve TableViewCell checkmark using NSUserDefaults in Swift

  • First of all create a class Item as data source with a name and selected property.

    class Item {
    let name : String
    var selected = false

    init(name: String) {
    self.name = name
    }
    }
  • Declare the data source array

    var myItems = [Item]()
  • Create the items this way

    let item = Item(name:"Foo") // your former string value, `selected` is false by default.
    myItems.append(item)
  • In applicationDidFinishLaunching register an empty string array as default value for key selectedCells

    let defaults = NSUserDefaults.standardUserDefaults()
    let defaultValues = ["selectedCells" : [String]()]
    defaults.registerDefaults(defaultValues)
  • To read all selected cells from user defaults get the string array and set the property selected of all corresponding items to true. Then reload the table view. The forced unwrapping is safe because the key/value is pre-registered and always non-optional. Important: Make sure that readDefaults() is always called after registering the default values.

    func readDefaults()
    {
    let defaults = NSUserDefaults.standardUserDefaults()
    let selectedItems = defaults.stringArrayForKey("selectedCells")!
    for item in myItems {
    item.selected = selectedItems.contains(item.name)
    }
    tableView.reloadData()
    }
  • In cellForRowAtIndexPath set both properties accordingly

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath)
    let item = myItems[indexPath.row]
    cell.textLabel!.text = item.name
    cell.accessoryType = item.selected ? .Checkmark : .None
    cell.selectionStyle = .None
    cell.tintColor = UIColor.greenColor()

    return cell
    }
  • To save the data filter all items whose selected property is true, map it to the names and save the array.

    func saveDefaults() {
    let selectedCells = myItems.filter { $0.selected }.map { $0.name }
    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.setObject(selectedCells, forKey:"selectedCells")
    }
  • Now you should change the model in didSelectRowAtIndexPath and reload the row. This is much more efficient (and recommended) than manipulating the cell

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let item = myItems[indexPath.row]
    item.selected = true
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
    }

Save checkmark in NSUserDefaults - dynamic TableView

#import "CycleTableViewController.h"
#import "SettingsTableViewController.h"

@interface CycleTableViewController (){
NSString *currentCategory; // pointer to the currently checked item
}
// other @property declarations here or in your .m file
#define CHECKED_KEY @"kCheckedBoxKey"

@property (nonatomic) int selectedRow;

@end

@implementation CycleTableViewController
@synthesize array;

- (void)viewDidLoad {

//load tickmark according to newCell;

array=@[@"21+7", @"22+6", @"23+5", @"24+4", @"25+3", @"26+2", @"28"];

[super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (void) viewWillAppear:(BOOL)animated {
self.selectedRow = [[[NSUserDefaults standardUserDefaults] objectForKey:@"cycle"] intValue];
}

- (void) viewWillDisappear:(BOOL)animated{
[[NSUserDefaults standardUserDefaults] setObject:@(indexPath.row) forKey:@"cycle"];
[[NSUserDefaults standardUserDefaults] synchronize];
}

#pragma mark - Table view data source

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

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIndentifier=@"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIndentifier forIndexPath:indexPath];

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

if(indexPath.row == self.selectedRow){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedRow = indexPath.row;
[self.tableView reloadData];
}

@end

iOS: How to save only one checkmark (for UITableView) in NSUserDefaults?

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.)

how to save table check mark after reload the view

You need to store the last checked row index so you can load that value the next time you bring up the view controller. Since you appear to only have one section you just need to save (and restore) the row index. NSUserDefaults is a good place to store this NSInteger value. You can save the row index each time a new selection is made. You can load the current value in the view controller's viewDidLoad method.

saving checkmark accessory value in nsuserdefaults and then retreving them

Try replacing this:

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
prefs = [setObject:lastIndexPath forKey:@"lastIndexPath"];

With this:

[[NSUserDefaults standardUserDefaults] setObject:lastIndexPath forKey:@"lastIndexPath"];

Your error is because you are invoking setObject:forKey: without specifying that your prefs object is calling it. So the compilor is not identifying it as a valid message. You are also trying to assing that messages output to your prefs object, which is not correct.

This said, I am pretty sure you cant store an NSIndexPath inside of a plist directly, you would either have to store as an NSNumber, NSString, or NSData.

This would look like this:

[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:lastIndexPath.row] forKey:@"lastIndexPath"];


Related Topics



Leave a reply



Submit