save and load data in UItableview - ios

I have some problem with saving and loading data in UITableView. After I press button2, I can't find my data that I saved(maybe I didn't save it).
My.h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray * arrayIdea;
NSMutableArray * arrayEdit;
IBOutlet UITableViewCell * cell;
}
#property(nonatomic,strong)IBOutlet UITextField * txtField;
#property(nonatomic,strong)IBOutlet UITableView * tabel1;
-(IBAction)button2:(id)sender;
-(IBAction)button1:(id)sender;
#end
My .m file:
#import "ViewController.h"
#interface ViewController ()<UITextFieldDelegate>
#end
#implementation ViewController
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrayIdea = [[NSMutableArray alloc] init];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (arrayIdea.count > 0) {
return arrayIdea.count;
}
return 0;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell1"];
}
cell.textLabel.text =[NSString stringWithFormat:#"%#", arrayIdea[indexPath.row]];
return cell;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
if(editingStyle == UITableViewCellEditingStyleDelete) {
[arrayIdea removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation: UITableViewRowAnimationFade];
}
}
-(IBAction)button1:(id)sender;{
[arrayIdea addObject:self.txtField.text];
[self.tabel1 reloadData];
self.txtField.text = #"";
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:arrayIdea forKey:#"savedstring"];
[defaults synchronize];
}
-(IBAction)button2:(id)sender;{
NSUserDefaults*defaults = [NSUserDefaults standardUserDefaults];
cell.textLabel.text =[defaults objectForKey:#"savedstring"];
}
#end

You need to encode/decode your array to be able to save it/ retrieve it in NSUserDefaults.
Save
NSData *dataSave = [NSKeyedArchiver archivedDataWithRootObject: arrayIdea];
[[NSUserDefaults standardUserDefaults] setObject:dataSave forKey:#"savedstring"];
[[NSUserDefaults standardUserDefaults] synchronize];
Read
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"savedstring"];
NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];

You can save and retrieve like this ..
Save
[[NSUserDefaults standardUserDefaults]setObject:arrayIdea forKey:#"savedstring"];
And retrieve
[[NSUserDefaults standardUserDefaults] objectForKey:#"savedstring"];

In cellForRowAtIndexpath, If you write code like below.
cell.textlabel.text = [[defaults objectForKey:#"saved string"] objectAtIndex:indexPath.row];
instead of passing array.
In numberOfRowsInSection you can pass
[[defalts objectForKey:#"saved string"] count];
You already called table reload method, so there is no need of button 2.
Please try.

Related

How to save the checkmarks in uitableview and show them when the user comes back again to the view?

I am using the following code for showing the checkmarks in the uitableview
{
// NSArray *tableContents;
NSMutableArray *selectedMarks; // You need probably to save the selected cells for use in the future.
}
#property (strong, nonatomic) IBOutlet UITableView *languageTableView;
#property (nonatomic, strong) NSArray *tableContents;
#end
#implementation QPLanguageSettingsController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initialisation];
selectedMarks = [NSMutableArray new];
}
#pragma mark - View Life Cycle
-(void)initialisation
{
_tableContents = [NSArray arrayWithObjects:#"English",#"Spanish",#"Russian",#"Arabic",#"Portuguese",#"French",#"German",#"German",#"German",#"German",#"German",#"German",#"German",#"German", nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableView delegate & datasources
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 14;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"newFriendCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//etc.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.textColor = [UIColor whiteColor];
cell.backgroundColor = [UIColor clearColor];
[cell setIndentationLevel:3];
[cell setIndentationWidth:10];
NSString *text = [_tableContents objectAtIndex:[indexPath row]];
//cell.isSelected = [selectedMarks containsObject:text] ? YES : NO;
cell.textLabel.text = text;
NSDictionary *item = [_tableContents objectAtIndex:indexPath.row];
if ([selectedMarks containsObject:item])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//if you want only one cell to be selected use a local NSIndexPath property instead of array. and use the code below
//self.selectedIndexPath = indexPath;
//the below code will allow multiple selection
NSDictionary *item = [_tableContents objectAtIndex:indexPath.row];
if ([selectedMarks containsObject:item])
{
[selectedMarks removeObject:item];
}
else
{
[selectedMarks addObject:item];
}
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
But the problem is that when i come again to the view controller all the checkmarks disappears. how to solve it. Remember i am using multiple selection in uitableview.
I tried the to get solution for your question.I got it successfully.It works perfectly.
This is sample one.Try this code.It works fine.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tableViewCheckMarkPreviousSelectionUpdate;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrProductSelection,*arrProductSelectDeSelectCheckMark;
NSArray *arrayFetchFromDefaults;
}
#end
#implementation ViewController
#synthesize tableViewCheckMarkPreviousSelectionUpdate;
- (void)viewDidLoad
{
[super viewDidLoad];
arrProductSelection = [[NSMutableArray alloc]initWithObjects:#"iPhone",#"iPad",#"iPod",#"iTV",#"iWatch",#"iMac",nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
arrayFetchFromDefaults = [userDefaults objectForKey:#"selectedcheckmark"];
arrProductSelectDeSelectCheckMark = [[NSMutableArray alloc]initWithArray:arrayFetchFromDefaults];
if(arrProductSelectDeSelectCheckMark.count == 0)
{
arrProductSelectDeSelectCheckMark = [[NSMutableArray alloc]init];
for(int j=0;j<[arrProductSelection count];j++)
{
[arrProductSelectDeSelectCheckMark addObject:#"deselected"];
}
}
[tableViewCheckMarkPreviousSelectionUpdate reloadData];
}
#pragma mark - UITableViewDataSource Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrProductSelection.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *strCell = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
if([[arrProductSelectDeSelectCheckMark objectAtIndex:indexPath.row] isEqualToString:#"deselected"])
cell.accessoryType = UITableViewCellAccessoryNone;
else
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.textLabel.text = [arrProductSelection objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - UITableViewDelegate Methods
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
#try
{
CGPoint touchPoint = [cell convertPoint:CGPointZero toView:tableViewCheckMarkSelectionUpdate];
NSIndexPath *indexPath = [tableViewCheckMarkSelectionUpdate indexPathForRowAtPoint:touchPoint];
NSLog(#"%#",arrProductSelectDeSelectCheckMark);
if([arrProductSelectDeSelectCheckMark count]==0)
{
for(int i=0; i<[arrProductSelection count]; i++)
{
[arrProductSelectDeSelectCheckMark addObject:#"deselected"];
}
}
if([[arrProductSelectDeSelectCheckMark objectAtIndex:indexPath.row] isEqualToString:#"deselected"])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arrProductSelectDeSelectCheckMark replaceObjectAtIndex:indexPath.row withObject:#"selected"];
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
[arrProductSelectDeSelectCheckMark replaceObjectAtIndex:indexPath.row withObject:#"deselected"];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:arrProductSelectDeSelectCheckMark forKey:#"selectedcheckmark"];
[defaults synchronize];
}
#catch (NSException *exception) {
NSLog(#"The exception is-%#",exception);
}
}
#end
You have multiple solutions:
Using a rational DB on the device like Core-data or SQLite which actually fits your use case but number 3 is more suitable for your use case.
Using NSUserDefaults:
At runtime, you use an NSUserDefaults object to read the defaults that your application uses from a user’s defaults database. NSUserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default
You can find an example here. But NSUserDefaults is to save settings/config/setup information or perhaps user info and NOT for the use case you need.
Using NSCoder which is in my opinion fits your use case.
you can create a Singleton and store data on it :
Singleton.h
#interface Singleton : NSObject
#property (nonatomic, strong) NSArray *rowsChecked;
+ (Singleton *)sharedInstance;
+ (NSArray *)getRowsChecked;
+ (void)setRowsChecked:(NSArray *)rowsChecked;
#end
Singleton.m
#import "Singleton.h"
#implementation Singleton
static Singleton *sharedObject;
+ (Singleton *)sharedInstance;
{
if (sharedObject == nil) {
static dispatch_once_t pred;
dispatch_once(&pred, ^{
sharedObject = [[Singleton alloc] init];
});
}
return sharedObject;
}
+ (NSArray *)getRowsChecked
{
Singleton *singleton = [Singleton sharedInstance];
return singleton.rowsChecked;
}
+ (void)setRowsChecked:(NSArray *)rowsChecked
{
Singleton *singleton = [Singleton sharedInstance];
singleton.rowsChecked= rowsChecked;
}
#end
and to access to your Singleton :
[[Singleton sharedInstance] getRowsChecked]
// or
[[Singleton sharedInstance] setRowsChecked:anArray];
Use the following code:
#import "ViewController.h"
#interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *languagesTableView;
#property (strong, nonatomic) NSArray *languagesArray;
#property (strong, nonatomic) NSMutableArray *checkMarksArray;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.languagesTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
self.languagesArray = [NSArray arrayWithObjects:#"English",#"Spanish",#"Russian",#"Arabic",#"Portuguese",#"French",#"German", nil];
self.checkMarksArray = [[NSMutableArray alloc]init];
if( [[NSUserDefaults standardUserDefaults]objectForKey:#"selectedRowsArray"])
{
self.checkMarksArray = [[[NSUserDefaults standardUserDefaults]objectForKey:#"selectedRowsArray"] mutableCopy];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.languagesArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *languagesCell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
languagesCell.textLabel.text = self.languagesArray[indexPath.row];
if([self.checkMarksArray containsObject:[NSNumber numberWithLong:indexPath.row]])
{
languagesCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
languagesCell.accessoryType = UITableViewCellAccessoryNone;
}
[[NSUserDefaults standardUserDefaults]setObject:self.checkMarksArray forKey:#"selectedRowsArray"];
[[NSUserDefaults standardUserDefaults]synchronize];
return languagesCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if([self.checkMarksArray containsObject:[NSNumber numberWithLong:indexPath.row]])
{
[self.checkMarksArray removeObject:[NSNumber numberWithLong:indexPath.row]];
}
else
{
[self.checkMarksArray addObject:[NSNumber numberWithLong:indexPath.row]];
}
[self.languagesTableView reloadData];
}
#end
Check this GitHub link:
https://github.com/k-sathireddy/TableViewSelectedCheckMarks

TableView in iOS Settings Bundle

I am a newbie on iOS Development and I am sorting out how am I going to have a table view with a checkmark on the settings bundle like this:
Is there any way to do it? Or is this just only available for specific iOS approved apps?
Looking forward for an answer. Thanks.
You can achieve this through Multi Value Element. When the user taps a preference containing a multi-value element, the Settings application displays a new page with the possible values to choose from. Google it for the tutorials if needed (Multivalue option for the settings bundle).
Here are the details : PSMultiValueSpecifier
If I am guessing right and you want to know how to display settings outside your app and in the iOS Settings, then check out this tutorial. It should get you started.
Taken out of the link below:
I have been searching around and couldn't find a boilerplate solution so created my own code for doing this. It supports the setting types Title, Group, Text Field, Multi Value and Toggle Switch.
It does NOT SUPPORT Slider.
This solution does support portrait AND landscape mode and can also handle changing over device orientations.
First off all I'm assuming that you are using the following code to read out your default values from the Settings.bundle.
- (void) registerDefaultsFromSettingsBundle
{
NSLog(#"Registering default values from Settings.bundle");
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
[defs synchronize];
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource: #"Settings" ofType: #"bundle"];
if(!settingsBundle)
{
NSLog(#"Could not find Settings.bundle");
return;
}
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent: #"Root.plist"]];
NSArray *preferences = [settings objectForKey: #"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for (NSDictionary *prefSpecification in preferences)
{
NSString *key = [prefSpecification objectForKey:#"Key"];
if (key)
{
// check if value readable in userDefaults
id currentObject = [defs objectForKey: key];
if (currentObject == nil)
{
// not readable: set value from Settings.bundle
id objectToSet = [prefSpecification objectForKey: #"DefaultValue"];
[defaultsToRegister setObject: objectToSet forKey: key];
NSLog(#"Setting object %# for key %#", objectToSet, key);
}
else
{
// already readable: don't touch
NSLog(#"Key %# is readable (value: %#), nothing written to defaults.", key, currentObject);
}
}
}
[defs registerDefaults: defaultsToRegister];
[defs synchronize];
}
Okay now you'll need 2 classes. SettingsTableViewController and MultiValueTableViewController.
SettingsTableViewController.h
//
// SettingsTableViewController.h
// Cochlear App
//
// Created by Gilles Lesire on 16/07/14.
// Free to use
//
#import <UIKit/UIKit.h>
#import "MultiValueTableViewController.h"
#interface SettingsTableViewController : UITableViewController <MultiValueDelegate> {
NSMutableArray *labelViews;
NSMutableArray *textViews;
NSMutableArray *settingsKeys;
NSMutableArray *settingsTableSections;
NSMutableArray *settingsTableData;
}
#end
SettingsTableViewController.m
//
// SettingsTableViewController.m
// Cochlear App
//
// Created by Gilles Lesire on 16/07/14.
// Free to use
////
#import "SettingsTableViewController.h"
#define labelCGRectX 25
#define labelCGRectY 25
#define labelCGRectWidth 140
#define labelCGRectHeight 21
#define typeGroup #"PSGroupSpecifier"
#define typeTitle #"PSTitleValueSpecifier"
#define typeToggleSwitch #"PSToggleSwitchSpecifier"
#define typeMultiValue #"PSMultiValueSpecifier"
#define typeTextField #"PSTextFieldSpecifier"
#interface SettingsTableViewController ()
#end
#implementation SettingsTableViewController
- (id)initWithStyle: (UITableViewStyle)style
{
self = [super initWithStyle: style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Track rotation changes
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(deviceOrientationDidChange) name: UIDeviceOrientationDidChangeNotification object: nil];
// Avoid tab bar to overlap tableview
self.edgesForExtendedLayout = UIRectEdgeAll;
self.tableView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
// Custom initialization
labelViews = [NSMutableArray arrayWithObjects: nil];
textViews = [NSMutableArray arrayWithObjects: nil];
settingsTableSections = [NSMutableArray arrayWithObjects: nil];
settingsTableData = [NSMutableArray arrayWithObjects: nil];
settingsKeys = [NSMutableArray arrayWithObjects: nil];
NSLog(#"Created arrays");
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource: #"Settings" ofType: #"bundle"];
if(!settingsBundle) {
NSLog(#"Could not find Settings.bundle");
} else {
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent: #"Root.plist"]];
NSArray *preferences = [settings objectForKey: #"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity: [preferences count]];
for (NSDictionary *prefSpecification in preferences) {
NSLog(#"%#", prefSpecification);
NSString *title = [prefSpecification objectForKey: #"Title"];
NSString *type = [prefSpecification objectForKey: #"Type"];
if([type isEqualToString: typeGroup]) {
// Create new section
[settingsTableSections addObject: title];
NSMutableArray *newSection = [NSMutableArray arrayWithObjects: nil];
[settingsTableData addObject: newSection];
} else {
// Add specification to last section
[[settingsTableData objectAtIndex: ([settingsTableData count] - 1)] addObject:prefSpecification];
}
}
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView
{
// Return the number of sections.
return [settingsTableSections count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[settingsTableData objectAtIndex: section] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [settingsTableSections objectAtIndex: section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Get the dictionary item
NSDictionary *prefSpecification = [[settingsTableData objectAtIndex: indexPath.section] objectAtIndex: indexPath.row];
NSString *title = [prefSpecification objectForKey: #"Title"];
NSString *key = [prefSpecification objectForKey: #"Key"];
NSString *type = [prefSpecification objectForKey: #"Type"];
// Define cell
UITableViewCell *cell;
// Keep tag of keys
[settingsKeys addObject: key];
int tag = [settingsKeys count] - 1;
if([type isEqualToString: typeTitle]) {
// Create cell
cell = [tableView dequeueReusableCellWithIdentifier: #"Cell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Set title
cell.textLabel.text = title;
// Add label
UILabel *labelView = [[UILabel alloc] initWithFrame: CGRectMake(labelCGRectX, labelCGRectY, labelCGRectWidth, labelCGRectHeight)];
labelView.text = [[NSUserDefaults standardUserDefaults] objectForKey: key];
labelView.textAlignment = NSTextAlignmentRight;
labelView.textColor = [UIColor grayColor];
cell.accessoryView = labelView;
}
if([type isEqualToString: typeToggleSwitch]) {
// Create cell
cell = [tableView dequeueReusableCellWithIdentifier: #"Cell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Set title
cell.textLabel.text = title;
// Add switch
UISwitch *switchView = [[UISwitch alloc] initWithFrame: CGRectZero];
cell.accessoryView = switchView;
switchView.tag = tag;
[switchView setOn: [[[NSUserDefaults standardUserDefaults] objectForKey: key] boolValue] animated: NO];
// Connect action to switch
[switchView addTarget: self action: #selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
}
if([type isEqualToString: typeTextField]) {
// Create cell
cell = [tableView dequeueReusableCellWithIdentifier: #"Cell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
int frameSize = self.view.frame.size.width;
UITextField *textField = [[UITextField alloc] initWithFrame: CGRectMake(15, 10, frameSize,labelCGRectHeight)];
textField.tag = tag;
textField.text = [[NSUserDefaults standardUserDefaults] objectForKey: key];
[textField addTarget: self
action: #selector(textFieldChanged:)
forControlEvents: UIControlEventEditingChanged];
[cell.contentView addSubview: textField];
// Tract text field
[textViews addObject: textField];
}
if([type isEqualToString: typeMultiValue]) {
// Create cell
cell = [tableView dequeueReusableCellWithIdentifier: #"MultiValueCell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Get value
int value = [[[NSUserDefaults standardUserDefaults] objectForKey: key] intValue];
NSArray *values = [prefSpecification objectForKey: #"Values"];
NSArray *titles = [prefSpecification objectForKey: #"Titles"];
NSString *multiValue = #"Unknown";
int index = [values indexOfObject: [NSString stringWithFormat: #"%d", value]];
if(index >= 0 && index < [values count]) {
multiValue = [titles objectAtIndex: index];
}
// Set title
cell.textLabel.text = title;
int frameSize = self.view.frame.size.width;
// Add label
UILabel *labelView = [[UILabel alloc] initWithFrame: CGRectMake((frameSize - labelCGRectWidth - 30), 12, labelCGRectWidth, labelCGRectHeight)];
labelView.textAlignment = NSTextAlignmentRight;
labelView.text = multiValue;
labelView.textColor = [UIColor grayColor];
[cell addSubview: labelView];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Track label
[labelViews addObject: labelView];
}
return cell;
}
- (void) switchChanged: (id) sender {
UISwitch* switchControl = sender;
NSString *key = [settingsKeys objectAtIndex: switchControl.tag];
NSNumber *numberValue = [NSNumber numberWithBool: switchControl.on];
[[NSUserDefaults standardUserDefaults] setObject: numberValue forKey: key];
}
- (void) textFieldChanged: (id) sender {
UITextField* textControl = sender;
NSString *key = [settingsKeys objectAtIndex: textControl.tag];
NSString *stringValue = textControl.text;
[[NSUserDefaults standardUserDefaults] setObject: stringValue forKey: key];
}
- (void) selectedMultiValue {
[self reloadTable];
}
- (void) deviceOrientationDidChange {
[self reloadTable];
}
- (void)prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
if ([[segue identifier] isEqualToString: #"changeMultiValue"])
{
MultiValueTableViewController *multiValueViewController =
[segue destinationViewController];
NSIndexPath *indexPath = [self.tableView
indexPathForSelectedRow];
// Get the dictionary item
NSDictionary *prefSpecification = [[settingsTableData objectAtIndex: indexPath.section] objectAtIndex: indexPath.row];
multiValueViewController.prefSpecification = prefSpecification;
multiValueViewController.delegate = self;
}
}
- (void) reloadTable {
for (UILabel *labelView in labelViews) {
[labelView removeFromSuperview];
}
for (UITextField *textView in textViews) {
[textView removeFromSuperview];
}
// Remove references to objects for garbage collection
labelViews = [NSMutableArray arrayWithObjects: nil];
textViews = [NSMutableArray arrayWithObjects: nil];
[self.tableView reloadData];
}
- (void) dealloc {
// Remove observers
[[NSNotificationCenter defaultCenter] removeObserver: self];
}
#end
MultiValueTableViewController.h
//
// MultiValueTableViewController.h
// Cochlear App
//
// Created by Gilles Lesire on 16/07/14.
// Free to use
//
#import <UIKit/UIKit.h>
#import "SettingsController.h"
#protocol MultiValueDelegate
- (void) selectedMultiValue;
#end
#interface MultiValueTableViewController : UITableViewController {
NSDictionary *prefSpecification;
}
#property (nonatomic) id<MultiValueDelegate> delegate;
#property (strong, nonatomic) NSDictionary *prefSpecification;
#end
MultiValueTableViewController.m
//
// MultiValueTableViewController.m
// Cochlear App
//
// Created by Gilles Lesire on 16/07/14.
// Free to use
//
#import "MultiValueTableViewController.h"
#interface MultiValueTableViewController ()
#end
#implementation MultiValueTableViewController
#synthesize prefSpecification;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *title = [prefSpecification objectForKey: #"Title"];
self.navigationItem.title = title;
// Avoid tab bar to overlap tableview
self.edgesForExtendedLayout = UIRectEdgeAll;
self.tableView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *values = [prefSpecification objectForKey: #"Values"];
// Return the number of rows in the section.
return [values count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: #"Cell" forIndexPath:indexPath];
NSString *key = [prefSpecification objectForKey: #"Key"];
NSArray *titles = [prefSpecification objectForKey: #"Titles"];
NSArray *values = [prefSpecification objectForKey: #"Values"];
NSString *title = [titles objectAtIndex: indexPath.row];
// Create cell
cell.selectionStyle = UITableViewCellSelectionStyleGray;
// Set title
cell.textLabel.text = title;
// If this is the selected value
if([[values objectAtIndex: indexPath.row] intValue] == [[[NSUserDefaults standardUserDefaults] objectForKey: key] intValue]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [prefSpecification objectForKey: #"Key"];
NSArray *values = [prefSpecification objectForKey: #"Values"];
NSNumber *value = [values objectAtIndex: indexPath.row];
[[NSUserDefaults standardUserDefaults] setObject: value forKey: key];
[self.delegate selectedMultiValue];
[self.tableView reloadData];
}
#end
Storyboard Now go the storyboard and create a TableViewController. Select the TableViewController and Choose "Editor" -> "Embed in" -> "Navigation controller".
Set the class of the TableViewController as SettingsTableViewController. Set the identifier of the cell as "Cell", add a second TableViewCell to the TableView and set it's identifier as "MultiValueCell". Add a second TableViewController, and CTRL+CLICK and drag from the MultiValueCell to the second TableViewController. Set the class of the second TableViewController as MultiValueTableViewController. Set the identifier of the cell in the second TableViewController as "Cell" too. That's it!
#import "SettingViewController.h"
NSInteger selectedIndex;
//Use this, it works for me
- (void)viewDidLoad
{
selectedIndex = 0;
[super viewDidLoad];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50.0f;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_arrayForSaveSetting count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (indexPath.row==selectedIndex) {
cell.accessoryType =UITableViewCellAccessoryCheckmark;
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
selectedIndex=indexPath.row;
[_tblSaveSetting reloadData];
}

How to use NSUserDefaults to save data from ViewController and retrieve it to TableViewController when app reruns

I'm desperate, been solving this for hours.. So I have a class "WishListItem", a TableViewController and a ViewController. I'm having difficulties in saving chunk of data and retrieving it from TableViewController? How to do this effectively?
I'm going to paste all my codes because I don't know if there something important that must be included to my question. So I'm sorry, please bear with me. Here it is.
ViewController.h:
#import <UIKit/UIKit.h>
#import "WishlistItem.h"
#interface JLSViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIBarButtonItem *addWishListButton;
#property (strong, nonatomic) IBOutlet UITextField *wishTextField;
#property (strong, nonatomic) IBOutlet UITextField *descTextField;
#property (strong, nonatomic) IBOutlet UIDatePicker *targetDatePicker;
#property WishlistItem *wishItem;
#end
ViewController.m
#import "JLSViewController.h"
#import "WishlistTableViewController.h"
#interface JLSViewController ()
#property NSMutableArray *wishlistItem;
#end
#implementation JLSViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSDate *myDate = self.targetDatePicker.date;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMM d, YYYY"];
NSString *prettyVersion = [dateFormat stringFromDate:myDate];
if (sender != self.addWishListButton) return;
if (self.wishTextField.text.length > 0) {
self.wishItem = [[WishlistItem alloc] init];
self.wishItem.wishlistItem = self.wishTextField.text;
self.wishItem.descWishItem = self.descTextField.text;
self.wishItem.targetDate = prettyVersion;
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:self.wishItem.wishlistItem forKey:#"itemWish"];
[defaults setObject:self.wishItem.descWishItem forKey:#"itemDesc"];
[defaults setObject:self.wishItem.targetDate forKey:#"itemDate"];
[defaults synchronize];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
#end
TableViewController.h
#import <UIKit/UIKit.h>
#import "DetailViewController.h"
#interface WishlistTableViewController : UITableViewController
- (IBAction)unwindToWishlistTableViewController:(UIStoryboardSegue *)unwindSegue;
#property NSMutableArray *wishlistItem;
#end
TableViewController.m
#import "WishlistTableViewController.h"
#import "WishlistItem.h"
#import "JLSViewController.h"
#import "DetailViewController.h"
#interface WishlistTableViewController ()
#end
#implementation WishlistTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.wishlistItem = [[NSMutableArray alloc]init];
}
- (IBAction)unwindToWishlistTableViewController:(UIStoryboardSegue *)unwindSegue {
JLSViewController *source = [unwindSegue sourceViewController];
WishlistItem *item = source.wishItem;
if (item != nil) {
[self.wishlistItem addObject:item];
[self.tableView reloadData];
}
}
- (IBAction)delete:(id)sender {
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
// Return the number of rows in the section.
return [self.wishlistItem count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"wishlistCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
WishlistItem *wish = [self.wishlistItem objectAtIndex:indexPath.row];
// Configure the cell...
//Set target date string
NSString *targetDate = [NSString stringWithFormat:#"Target Date: %#", wish.targetDate];
//Set wishlist item string
NSString *wishItemString = wish.wishlistItem;
cell.textLabel.text = wishItemString;
cell.detailTextLabel.text = targetDate;
return cell;
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
WishlistItem *wish = [self.wishlistItem objectAtIndex:indexPath.row];
DetailViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"dvcID"];
dvc.wishItemStr = wish.wishlistItem;
dvc.dateItemStr = wish.targetDate;
dvc.descItemStr = wish.descWishItem;
[self.navigationController pushViewController:dvc animated:YES];
}
// Delete row/cell
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove the row from data model
[self.wishlistItem removeObjectAtIndex:indexPath.row];
// Request table view to reload
[tableView reloadData];
}
#end
From my ViewController, i want to save every entries that's being added and retrieve it later to my TableViewController. Thank you and I'm really sorry for posting all my codes because I'm really frustrated already, been solving this for several hours. Thank you in advance.
I've used NSUserDefaults in my prepareForSegue. But I think I can't retrieve it properly from my TableViewController.
I've included my "Saving Data" only using NSUserDefaults because I don't know how I will implement the "Loading Data" to my TableViewController.
I'm sorry for my code. Just a beginner for now.
My only goal is just to save my 3 strings(Wish Item, Wish Description, Target Date) and I just want to retrieve those data every time the app reruns..
-(void)yourSaveMethod
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:#"My saved Data" forKey:#"infoString"];
}
-(void)yourLoadMethod
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
cell.tableview.text = [defaults objectForKey:#"infoString"];
}``
#Rhenzzz : you have to replace this
cell.textLabel.text = wishItemString;
cell.detailTextLabel.text = targetDate;
by
cell.textLabel.text = itemWish ;
cell.detailTextLabel.text = itemDate;
in Jay's code.
To save your array state use this ie in view controller
NSString *valueToSave = #"someValue";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"preferenceName"];
[[NSUserDefaults standardUserDefaults] synchronize];
use this where you want to retrieve the variable ie. intableViewController
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"preferenceName"];
I would recommend Core Data for this as well.
However, if you really wanted to use NSUserDefaults you should keep an NSArray of NSDictionarys in a single key. The way you're doing things now, you would only be able to display one item in your UITableView at a time because you overwrite the same keys each time you prepareForSegue.
Put this in a separate header file and import in where necessary:
#define WISH_ITEMS_KEY #"wishItems"
Execute this code once (possibly in the AppDelegate like so):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults registerDefaults:#{WISH_ITEMS_KEY: #[]}];
[defaults synchronize];
return YES;
}
Then in your prepareForSegue:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *wishItems = [[defaults arrayForKey:WISH_ITEMS_KEY] mutableCopy];
[wishItems addObject:#{#"itemWish": self.wishItem.wishlistItem,
#"itemDesc": self.wishItem.descWishItem,
#"itemDate": self.wishItem.targetDate}];
[defaults setObject:wishItems forKey:WISH_ITEMS_KEY];
[defaults synchronize];
In your TableViewController's viewDidLoad:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.wishlistItem = [[defaults arrayForKey:WISH_ITEMS_KEY] mutableCopy];
Then in your cellForRowAtIndexPath you can retrieve each item and set your cell:
NSDictionary *itemDictionary = self.wishlistItem[indexPath.row];
NSString *itemWish = itemDictionary[#"itemWish"];
NSString *itemDesc = itemDictionary[#"itemDesc"];
NSString *itemDate = itemDictionary[#"itemDate"];
Hope that helps.

Saving the selected row for UITableView

I'm trying to save the selected row for my UITableView. So, when the user comes back to the screen, it shows their last selection.
This is the code I tried, which, i thought would do the trick:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.lastIndexPathUsed = indexPath;
NSData *responseData = [NSKeyedArchiver archivedDataWithRootObject:indexPath];
[[NSUserDefaults standardUserDefaults] setObject:responseData forKey:#"IndexPathData"];
[[NSUserDefaults standardUserDefaults] synchronize];
[tableView reloadData];
}
Then in my viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
NSData *responseData = [[NSUserDefaults standardUserDefaults]objectForKey:#"IndexPathData"];
NSIndexPath *index = [NSKeyedUnarchiver unarchiveObjectWithData:responseData];
self.lastIndexPath = index;
}
However, responseData hasn't have the index path saved. Its always NULL. Even in the didSelectRowAtIndexPath method.
Anyone know of a better way to do this?
You can save it as two values and recreate the NSIndexPath later:
Save indexPath.row and indexPath.section separately then recreate it with:
[NSIndexPath indexPathForRow:inSection:]
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUserDefaults *userdefaults = [NSUserDefaults standardUserDefaults];
[userdefaults setObject:[NSString stringWithFormat:#"%d",indexPath.row] forKey:#"lastIndexPathUsed"];
}
Then in viewDidLoad Method
-(void)viewDidLoad
{
[super viewDidLoad];
self.lastIndexPath = [[NSUserDefaults standardUserDefaults] objectForKey:#"lastIndexPathUsed"];
}

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

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];
}
}
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 :)
This is a basic example of how to create an array of NSIndexPaths based on the current selection of the table and then saving that array into NSUserDefaults.
-(void)viewDidLoad
{
[super viewDidLoad];
for (NSIndexPath *indexPath in [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"mySavedMutableArray"]) {
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}
Here you can add objects to the array as they are selected
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"mySavedMutableArray"] addObject:indexPath];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Here you'll remove the deselected object from the array.
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"mySavedMutableArray"] removeObject:indexPath];
[[NSUserDefaults standardUserDefaults] synchronize];
}
The simplest way to get your code working is just put one line in view did load method as follow:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if([defaults valueForKey:#"lastIndexPath"])
_lastIndexPath = [defaults valueForKey:#"lastIndexPath"];
This will solve your problem :)
Happy Coding :)

Resources