How to Save a button selection in NSUser Defaults - ios

*
//
// DetailTableViewController.m
// BeautifulWorld
//
// Created by Mahesh on 10/27/15.
// Copyright © 2015 Mahesh. All rights reserved.
//
#import "DetailTableViewController.h"
#import "DetailTableViewCell.h"
#import "ContentViewController.h"
#import "TableViewHeader.h"
#import UIKit;
#interface DetailTableViewController ()
#end
#implementation DetailTableViewController{
NSMutableArray* selectedPlaces;
NSDictionary* place;
NSArray* places;
}
DetailTableViewCell * detailcell ;
- (void)viewDidLoad {
[super viewDidLoad];
selectedPlaces = [[NSMutableArray alloc]init];
selectedItems = [[NSMutableArray alloc] init];
//TODO:- NSUserDefaults Attempt
selectedPlaces = [NSMutableArray arrayWithArray:(NSArray *)[[NSUserDefaults standardUserDefaults] objectForKey:#"selectedPlaces"]];
if(selectedPlaces == nil){
selectedPlaces = [[NSMutableArray alloc] init];
}else{
NSLog(#"Saved to Defaults");
}
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
detailcell.loveImageView.highlighted = YES;
self.navigationItem.title = _DetailTableModal[0];
//Wonders Of The World
//[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
//Your code goes in here
//NSLog(#"Main Thread Code");
if ([self.navigationItem.title isEqualToString:#"Wonders Of The World"])
{
NSArray* titleArray = #[#"Pyramid at 'Chichen Itza'",
#"Christ the Redeemer",
#"Great Wall of China",
#"Machu Picchu",
#"Petra",
#"Taj Mahal",
#"Colosseum ",];
Title = [titleArray mutableCopy];
NSArray* descriptionArray = #[#"Yucatan, Mexico",
#"Rio de Janeiro - RJ, Brazil",
#"China",
#"Peru",
#"Wadi Musa,Jordan",
#"Agra,Uttar Pradesh,India",
#"Rome,Italy",];
Description = [descriptionArray mutableCopy];
NSArray* imageArray = #[#"1ChichenItza.jpg",
#"2ChristtheRedeemer.jpg",
#"3GreatWallofChina.jpg",
#"4MachuPicchu.jpg",
#"5Petra.jpg",
#"6Tajmahal.jpg",
#"7Colosseum.jpg",];
Image = [imageArray mutableCopy];
}
// }];
if ([self.navigationItem.title isEqualToString:#"Sky Scrapers"])
{
NSArray* titleArray = #[#"Burj Kalifa",
#"Eiffel Tower",
#"Empire State Building",
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewWillAppear:(BOOL)animated{
[self myValue];
self.tabBarController.tabBar.hidden = NO;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return Title.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * CellIdentifier = #"DetailCell";
detailcell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
int row = (int)[indexPath row];
detailcell.DetailTableCellTitle.text = Title[row];
detailcell.DetailTableCellDescription.text = Description[row];
detailcell.DetailTableCellImageView.image= [UIImage imageNamed:Image[row]];
if([selectedItems containsObject:indexPath]){
//high
detailcell.loveImageView.highlighted = YES;
}else{
//gray
detailcell.loveImageView.highlighted = NO;
}
// Adding Tag To The Love Button
// detailcell.loveImageView.tag = indexPath.row;
detailcell.favouriteButton.tag = indexPath.row;
// Adding Tap Guesture To Love Button
detailcell.loveImageView.userInteractionEnabled = YES;
// UITapGestureRecognizer *tapGesture1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(loveImageTapped:)];
// tapGesture1.numberOfTapsRequired = 1;
// [detailcell.loveImageView addGestureRecognizer:tapGesture1];
[detailcell.favouriteButton addTarget:self action:#selector(loveImageTapped:) forControlEvents:UIControlEventTouchUpInside];
return detailcell;
}
#pragma mark Delete Rows With Animation
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
[Image removeObjectAtIndex:indexPath.row];
[Description removeObjectAtIndex:indexPath.row];
[Title removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
NSIndexPath * rowToReload = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
NSArray * rowsToReload = [NSArray arrayWithObjects:rowToReload, nil];
[tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationLeft];
}
#pragma mark Love Button Tapped
-(void)loveImageTapped:(UIButton*)sender {
sender.selected = !sender.selected; //calling your method
[self saveMyValue:sender.selected];
if (sender.selected) {
[sender setBackgroundImage:[UIImage imageNamed:#"HeartSelectedSmall"] forState:UIControlStateNormal];
[selectedPlaces addObject:selectedPlaces];
}else{
[sender setBackgroundImage:[UIImage imageNamed:#"Heart"] forState:UIControlStateNormal];
}
[self.tableView reloadData];
} // Your Methods Added
// Set the value
- (void)saveMyValue:(BOOL)myValue {
[[NSUserDefaults standardUserDefaults] setInteger:[NSNumber numberWithBool:myValue ].integerValue forKey:#"myActionKeyHere"];
[[NSUserDefaults standardUserDefaults] synchronize];
} // Your Methods Added
// Get the value
- (NSInteger)myValue {
NSInteger myValue = [[NSUserDefaults standardUserDefaults] integerForKey:#"myActionKeyHere"];
return myValue ;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Navigation To The Detail Content View.
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
ContentViewController * contentView = [ segue destinationViewController];
NSIndexPath * myindexpath = [self.tableView indexPathForSelectedRow];
int row = (int)[myindexpath row];
contentView.ContentModal = #[Title[row],Description[row],Image[row]];
}
}
#end Did The Same. Can you please explain me a bit more. What to do in cell for row at index path
*

You save it like this if its a BOOL, otherwise just change to NSInteger if you want multiple options etc:
// Set the value
- (void)saveMyValue:(BOOL)myValue {
[[NSUserDefaults standardUserDefaults] setInteger:[NSNumber numberWithBool:myValue ].integerValue forKey:#"myActionKeyHere"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
// Get the value
- (NSInteger)myValue {
NSInteger myValue = [[NSUserDefaults standardUserDefaults] integerForKey:#"myActionKeyHere"];
return myValue ;
}

#Hauzin did tell you the way with NSUserDefaults.
By the way, I have an other idea about your case.
First of all, the type of the button's selection status is BOOL type.
So we have to box the BOOL value as NSNumber value. (with [NSNumber numberWithBool:xxx])
And then, if you have a UITableView and the UITableView needs a number of button's selection status, you can save the Button selection status as a NSArray.
Then you could write a method with a NSArray type argument to create the new UITableView. (e.g: - (void)setupXXXtableViewWithButtonStatus:(NSArray *)buttonStatusArray;)

If you want to save button state in NSUserDefault you can use following code.
NSUserDefaults *udefaults=[NSUserDefaults standardUserDefaults];
if (btn.selected) {
[udefaults setBool:YES forKey:#"isSelected"];
}else{
[udefaults setBool:NO forKey:#"isSelected"];
}
To get the state of button you can use.
NSUserDefaults *udefaults=[NSUserDefaults standardUserDefaults];
BOOL isButtonSelected = [udefaults boolForKey:#"isSelected"];
Also, don't forget to call synchronize on udefaults like this.
[udefaults synchronize];
Hope, it helps.

Related

UITableView - move people from one section to another

I would like to create a tableview where I can move people from different departments into other departments, and I have some code posted below.
I have an issue with this, I can never seem to get it to get the usual ui gadget to move rows. I don't want the user to edit/delete the rows; simply move them about however the "move" buttons never seem to appear.
Is there something I am doing wrong?
Also I am not sure if I am doing the move code right.
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Departments";
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.tableView.allowsSelectionDuringEditing = YES;
_objects = [NSMutableArray array];
NSDictionary *sales = #{ #"name" : #"sales",
#"employees" : #[ #"Mike", #"Tom", #"Alex"] };
NSDictionary *marketing = #{ #"name" : #"marketing",
#"employees" : #[ #"Heather", #"Richard", #"Simon"] };
[_objects addObject:sales];
[_objects addObject:marketing];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
}
#pragma mark - IBActions
-(IBAction) editButton:(id)sender
{
[self setEditing:!self.editing animated:YES];
}
#pragma mark - UITableView delegate
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return [_objects count];
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *department = [_objects objectAtIndex:section];
NSArray *employees = department[#"employees"];
return [employees count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellId" forIndexPath:indexPath];
// Configure the cell...
NSDictionary *department = [_objects objectAtIndex:indexPath.section];
NSArray *employees = department[#"employees"];
NSString *employeeName = [employees objectAtIndex:indexPath.row];
cell.textLabel.text = employeeName;
return cell;
}
-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSDictionary *department = [_objects objectAtIndex:section];
return department[#"name"];
}
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
if( fromIndexPath == toIndexPath ) return;
NSDictionary *department = [_objects objectAtIndex:fromIndexPath.section];
NSArray *employees = department[#"employees"];
NSString *employeeName = [employees objectAtIndex:fromIndexPath.row];
[self.tableView beginUpdates];
[_objects removeObjectAtIndex:fromIndexPath.row];
[_objects insertObject:employeeName atIndex:toIndexPath.row];
[self.tableView endUpdates];
[tableView reloadData];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
if (indexPath.section == 1 && [_objects count] > 1)
{
return YES;
}
return NO;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if(editingStyle == UITableViewCellEditingStyleDelete){
[_objects removeObjectAtIndex:indexPath.row];
NSArray *rows = [NSArray arrayWithObject:indexPath];
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
}
call this method after your array initialised. [self.tableView reloadData]
This will load the table data once again.

Xcode : Storyboard and state preservation of the view controllers after quitting

I am new to programming in Xcode and I am having a problem in my app (a ToDo list). Everything works just fine but when the app is quit (Not minimised) the main view controller doesn't save what is on it (A problem if you have a ToDo list). Now I want to know what code I would have to implement in order to preserve the state of a view controller upon exit and where? (The app delegate or in my main view controller window)
.m file:
#implementation RHTaskListViewController
#synthesize tasks = _tasks;
-(id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self)
{
//custom
}
return self;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tasks = [[NSMutableArray alloc] init];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
//Segue from Add task to task list
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddTaskSegue"])
{
UINavigationController *navCon = segue.destinationViewController;
RHAddTaskViewController *addTaskViewController = [navCon.viewControllers objectAtIndex:0];
addTaskViewController.taskListViewController = self;
}
else if ([segue.identifier isEqualToString:#"EditDoneTaskSegue"] || [segue.identifier isEqualToString:#"EditNotDoneTaskSegue"])
{
RHEditTaskViewController *editTaskViewController = segue.destinationViewController;
editTaskViewController.task = [self.tasks objectAtIndex:self.tableView.indexPathForSelectedRow.row];
}
}
//Segue from Add task to task list
//Move Items
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
RHTask *movedTask = [self.tasks objectAtIndex:fromIndexPath.row];
[self.tasks removeObjectAtIndex:fromIndexPath.row];
[self.tasks insertObject:movedTask atIndex:toIndexPath.row];
}
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
//Move Items
//Delete Items
-(void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.tasks removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert)
{
}
}
//Delete Items
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tasks.count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *NotDoneCellIdentifier = #"NotDoneTaskCell";
static NSString *DoneCellIdentifier = #"DoneTaskCell";
RHTask *currentTask = [self.tasks objectAtIndex:indexPath.row];
NSString *cellIdentifier = currentTask.done ? DoneCellIdentifier : NotDoneCellIdentifier;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
//Saving the tasks
//[[NSUserDefaults standardUserDefaults] setString:saveTask forKey:#"taskSaved"];
//Saving the tasks
cell.textLabel.text = currentTask.name;
return cell;
}
#pragma mark - IBActions
-(void)editButtonPressed:(id)sender
{
self.editing = !self.editing;
}
#end
.h file:
#import <UIKit/UIKit.h>
#interface RHTaskListViewController : UITableViewController
#property (nonatomic, strong) NSMutableArray *tasks;
-(IBAction)editButtonPressed:(id)sender;
#end
U can use NSUserDefaults to achieve your goal.
Take this tutorial link
Main code:
For saving:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"key1" forKey:#"todo1"];
[defaults synchronize]; // do NOT forget this line!
For retrieving:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *todo1 = [defaults objectForKey:#"key1"];
Just keep in mind , u can save NSArray, NSDictionary, NSString, NSNumber and all object that conforms to NSCoping protocol.
As gran33 already noted you can use NSUserDefaults to store your app data.
If your todo list more complex than just a list of tasks (i.e. each task has more properties like time,description,location etc...) I recommend using core data to store your data. Take a look here for a CoreData tutorial.

Update core data object on UITableViewCell touch

I have a simple todo app, where a user can touch a cell to check/uncheck a task. But I am not sure how to update Core Data setting the boolean value of completed to yes.
Here is my code:
//
// PakkelisteViewController.m
// Sommerleir
//
// Created by Ronny-André Bendiksen on 08.05.14.
// Copyright (c) 2014 Arbeidernes Ungdomsfylking. All rights reserved.
//
#import "PakkelisteViewController.h"
#import "AUFToDoItem.h"
#import "TodoCell.h"
#interface PakkelisteViewController ()
#property NSMutableArray *toDoItems;
-(IBAction)addNewToDoItem;
#end
#implementation PakkelisteViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.toDoItems = [[NSMutableArray alloc] init];
[self loadInitialData];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
-(void)viewWillAppear:(BOOL)animated
{
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"AUFToDoItem"];
self.toDoItems = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
[self.tableView reloadData];
}
-(void)loadInitialData
{
// check if user has already been using this functionality
BOOL hasRunBefore = [[NSUserDefaults standardUserDefaults] boolForKey:#"PakkelisteHasRun"];
if (!hasRunBefore)
{
NSLog(#"Has not run");
[self.toDoItems addObjectsFromArray:#[#"Badetøy", #"Skrivesaker", #"Lommepenger", #"Godt humør"]];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"PakkelisteHasRun"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else
{
NSLog(#"Already run");
}
}
-(IBAction)addNewToDoItem
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Legg til ny" message:nil delegate:self cancelButtonTitle:#"Avbryt" otherButtonTitles:#"Legg til", nil];
[alertView setAlertViewStyle:UIAlertViewStylePlainTextInput];
[[alertView textFieldAtIndex:0] setPlaceholder:#"Rent undertøy"];
[[alertView textFieldAtIndex:0] setAutocapitalizationType:UITextAutocapitalizationTypeSentences];
[alertView show];
}
-(BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
NSString *inputText = [[alertView textFieldAtIndex:0] text];
if ([inputText length] > 0)
{
return YES;
}
else
{
return NO;
}
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
NSManagedObjectContext *context = [self managedObjectContext];
// Create a new managed object
NSManagedObject *toDoItem = [NSEntityDescription insertNewObjectForEntityForName:#"AUFToDoItem" inManagedObjectContext:context];
[toDoItem setValue:[alertView textFieldAtIndex:0].text forKey:#"itemName"];
[toDoItem setValue:[NSDate date] forKey:#"creationDate"];
[toDoItem setValue:[NSNumber numberWithBool:YES] forKey:#"completed"];
[self.toDoItems addObject:toDoItem];
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
[self dismissViewControllerAnimated:YES completion:nil];
[self.tableView reloadData];
}
}
- (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
{
// Return the number of rows in the section.
return self.toDoItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
TodoCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[TodoCell alloc] init];
}
NSManagedObject *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
cell.title.text = [toDoItem valueForKey:#"itemName"];
if ([[toDoItem valueForKey:#"completed"] boolValue] == 1)
{
cell.checkbox.image = [UIImage imageNamed:#"checkbox_on.png"];
}
else
{
cell.checkbox.image = [UIImage imageNamed:#"checkbox_on.png"];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
[tableView deselectRowAtIndexPath:indexPath animated:NO];
AUFToDoItem *tappedItem = [self.toDoItems objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
*/
}
-(NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:#selector(managedObjectContext)]) {
context = [delegate managedObjectContext];
}
return context;
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObjectContext *context = [self managedObjectContext];
if (editingStyle == UITableViewCellEditingStyleDelete) {
[context deleteObject:[self.toDoItems objectAtIndex:indexPath.row]];
NSError *error = nil;
if (![context save:&error])
{
NSLog(#"Can't delete! %# %#", error, [error localizedDescription]);
return;
}
[self.toDoItems removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#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.
}
*/
#end
Change:
tappedItem.completed = !tappedItem.completed;
to:
tappedItem.completed = #(![tappedItem.completed boolValue]);
Which is a minimal code unpacking and re packing of the bool value in an NSNumber instance.
Also, in your if statement, don't check if a BOOL value == 1 because that isn't necessarily true. Just say:
if ([tappedItem.completed]) { ...
You also appear to have a typo in the names of the checkbox images you're using.
What if move the code to update the status of your cell in tableView:tableView didSelectRowAtIndexPath:? In addition, can you explain what you mean with But I am not sure how to update Core Data setting the boolean value of completed to yes?
After updating the status of your managed object you save the context you are using, then you can perfom a reload on the entire table or on a specific index path.
BOOL hasTap = ![tappedItem.completed boolValue];
tappedItem.completed = #(hasTap); // or [NSNumber numberWithBool:hasTap];
// save
// reload
I really follow Jonathan's comment. A NSFetchedResultsController is made to wotk with UITableViews (or UICollectionViews). You can set its delegate, NSFetchedResultsControllerDelegate, to listen and handle for inserting, deleting, moving rows (and section).
An tutorial would be Core Data Tutorial for iOS: How To Use NSFetchedResultsController.

Saving Method for a button

this is my code in my .m file
#interface HomeWorkViewController ()
#end
#implementation HomeWorkViewController
#synthesize adView;
#synthesize myTableView, numbers;
-(void) viewDidLoad
{
adView.delegate=self;
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
// check here if key exists in the defaults or not, if yes the retrieve results in array
if([[NSUserDefaults standardUserDefaults] objectForKey:#"numberArray"] != nil) {
self.numbers = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"numberArray"]];
}
//Register for the notification when user go to background or minimize the app, just save the array objects in the defaults
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(appWillGoToBackground:)
name:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication]];
//Add the Add button
UIBarButtonItem * addButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target: self action: #selector(insertNewObject)];
self.navigationItem.rightBarButtonItem = addButton;
}
-(void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.myTableView setEditing:editing animated:animated];
}
-(void)appWillGoToBackground:(NSNotification *)note {
NSLog(#"terminate");
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:self.numbers forKey:#"numberArray"];
[defaults synchronize];
}
-(void)insertNewObject{
//Display a UIAlertView
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Enter HomeWork" message: #"" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//Only perform the following actions if the user hits the ok button
if (buttonIndex == 1)
{
NSString * tmpTextField = [alertView textFieldAtIndex:0].text;
if(!self. numbers){
self.numbers = [[NSMutableArray alloc]init];
}
[self.numbers insertObject:tmpTextField atIndex:0];
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.myTableView insertRowsAtIndexPaths:#[indexPath]withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.numbers.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];
}
cell.textLabel.text = [self.numbers objectAtIndex:indexPath.row];
return cell;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
//remove our NSMutableArray
[self.numbers removeObjectAtIndex:indexPath.row];
//remove from our tableView
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (void)tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath
{
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner
{
adView.hidden=FALSE;
NSLog(#"Has ad, showing");
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
adView.hidden=TRUE;
NSLog(#"Has no ads, hiding");
}
-(void)dealloc
{
[adView release];
[super dealloc];
}
#end
I have a saving method there but I want to save everything that I changed in the table by clicking a button. How do i do that?
I want to put a toolbar with a button that says back to go to the home screen, and link this button to save everything that was done to the table like delete, switch order and add.
You're almost there :)
You are using the numbers array as the data model for the table.
Make sure that this array is always updated when the table is manipulated. (For example, you need to reorder the numbers array in moveRowAtIndexPath. Currently, you do nothing in that method)
To save the model using a button, just create a UIButton in the Interface Builder and connect it to the following action:
- (IBAction)saveButtonWasPressed:(id)sender {
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:self.numbers forKey:#"numberArray"];
[defaults synchronize];
}
Maybe you also want to pop the tableviewcontroller from the navigationcontroller stack if you also want to leave the controller.

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