ios 7 uitableview cell long press to change value of core data attribute

ios, ios7, long-press, uigesturerecognizer, uitableview

Solution

Here is how you handle a long press:

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

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

    UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
                     initWithTarget:self action:@selector(handleLongPress:)];
    lpgr.minimumPressDuration = 1.0; //seconds
    [cell addGestureRecognizer:lpgr];

    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer 
{
            CGPoint p = [gestureRecognizer locationInView:self.tableView];

            NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
            if (indexPath == nil)
               NSLog(@"long press on table view but not on a row");
            else
            {
                 if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
                     NSLog(@"UIGestureRecognizerStateEnded");
                     //Do Whatever You want on End of Gesture
                 }
                 else if (gestureRecognizer.state == UIGestureRecognizerStateBegan){

                     UIAlertView *alert = [[UIAlertView alloc] initWithTitle: @"Announcement" message: @"You have long-pressed the row...!" delegate: nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
                     [alert show];
                     [alert release];
                     NSLog(@"UIGestureRecognizerStateBegan.");


                     NSLog(@"long press on table view at row %d", indexPath.row);

                     // Update ToDoStatus
                    [self.tableView reloadData];
                    //Do Whatever You want on Began of Gesture
                 }
            }
}

Your model will keep track of ToDoStatus in your model and then decide how that will be displayed in the UI.

Problem

I am using core data with an entity and several attributes. One of the attributes is named ToDoStatus. The list of the entity records are shown on a tableview and I want to implement following requirement: 1. When the user makes a long press on a cell (about 1 second), the record pressed must change its ToDoStatus value to "Done" and then reload the tableview not showing records with ToDoStatus = "Done". This is my current code: ``` #import "RootViewController.h" #import "AddToDoViewController.h" #import "EditToDoViewController.h" #import "MenuViewController.h" @interface RootViewController () - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath; @end @implementation RootViewController @synthesize fetchedResultsController, managedObjectContext,AddToDoButton,MenuToDoButton; #pragma mark - #pragma mark View lifecycle - (void)viewDidLoad { [super viewDidLoad]; // [self setTitle:@"Today"]; [[self navigationItem] setRightBarButtonItem:[self editButtonItem]]; self.editButtonItem.tintColor = [UIColor redColor]; UILabel *lblTitle = [[UILabel alloc] init]; lblTitle.text = @"Today"; lblTitle.backgroundColor = [UIColor clearColor]; lblTitle.textColor = [UIColor blueColor]; lblTitle.shadowColor = [UIColor whiteColor]; lblTitle.shadowOffset = CGSizeMake(0, 1); lblTitle.font = [UIFont fontWithName:@"Noteworthy" size:25.0]; [lblTitle sizeToFit]; self.navigationItem.titleView = lblTitle; [self.editButtonItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIFont fontWithName:@"Noteworthy" size:20], NSFontAttributeName, [UIColor blueColor], NSForegroundColorAttributeName, nil] forState:UIControlStateNormal]; self.tableView.delegate = self; self.tableView.dataSource = self; NSError *error = nil; if (![[self fetchedResultsController] performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } - (void) viewWillAppear:(BOOL)animated{ NSError *error = nil; if (![[self fetchedResultsController] performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } [self.tableView reloadData]; } - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath]; [[cell textLabel] setText:[[managedObject valueForKey:@"thingName"] description]]; NSString *myString = [NSString stringWithFormat:@"%@",[[managedObject valueForKey:@"todoYear"] description]]; UIButton *urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(15, 25, 18, 18)]; [urgentButton setImage:[UIImage imageNamed:@"urgent"]forState:UIControlStateNormal]; [cell addSubview:urgentButton]; UIButton *yellowButton = [[UIButton alloc]initWithFrame:CGRectMake(305, 5, 10, 40)]; [yellowButton setImage:[UIImage imageNamed:@"Red"]forState:UIControlStateNormal]; [cell addSubview:yellowButton]; UIButton *doneButton = [[UIButton alloc]initWithFrame:CGRectMake(33, 27, 18, 18)]; [doneButton setImage:[UIImage imageNamed:@"alldone"]forState:UIControlStateNormal]; [cell addSubview:doneButton]; UIButton *doneButton2 = [[UIButton alloc]initWithFrame:CGRectMake(53, 27, 18, 18)]; [doneButton2 setImage:[UIImage imageNamed:@"alldone"]forState:UIControlStateNormal]; [cell addSubview:doneButton2]; UIButton *doneButton3 = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)]; [doneButton3 setImage:[UIImage imageNamed:@"urgent"]forState:UIControlStateNormal]; [cell addSubview:doneButton3]; [[cell detailTextLabel] setText:@" "]; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; cell.textLabel.textColor = [UIColor blueColor]; cell.textLabel.font = [UIFont fontWithName:@"Noteworthy" size:22.0f]; cell.detailTextLabel.font = [UIFont fontWithName:@"Noteworthy" size:15.0f]; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { EditToDoViewController *detailViewController = [[EditToDoViewController alloc] initWithNibName:@"EditToDoViewController" bundle:nil]; NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath]; detailViewController.selectedObject = selectedObject; //[self.navigationController pushViewController:detailViewController animated:YES]; [self presentViewController:detailViewController animated:YES completion:nil]; } #pragma mark - #pragma mark Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [[fetchedResultsController sections] count]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section]; return [sectionInfo numberOfObjects]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"] autorelease]; } [self configureCell:cell atIndexPath:indexPath]; return cell; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { NSManagedObjectContext *context = [fetchedResultsController managedObjectContext]; [context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]]; NSError *error = nil; if (![context save:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath; { NSMutableArray *things = [[fetchedResultsController fetchedObjects] mutableCopy]; // Grab the item we're moving. NSManagedObject *thing = [[self fetchedResultsController] objectAtIndexPath:sourceIndexPath]; // Remove the object we're moving from the array. [things removeObject:thing]; // Now re-insert it at the destination. [things insertObject:thing atIndex:[destinationIndexPath row]]; // All of the objects are now in their correct order. Update each // object's displayOrder field by iterating through the array. int i = 0; for (NSManagedObject *mo in things) { [mo setValue:[NSNumber numberWithInt:i++] forKey:@"displayOrder"]; } [things release], things = nil; [managedObjectContext save:nil]; } #pragma mark - #pragma mark Fetched results controller - (IBAction)AddToDoAction:(id)sender { AddToDoViewController *viewController = [[AddToDoViewController alloc] init]; [self presentViewController:viewController animated:YES completion:nil]; } #pragma mark Fetched results controller - (IBAction)MenuToDoAction:(id)sender { MenuViewController *viewController = [[MenuViewController alloc] init]; [self presentViewController:viewController animated:YES completion:nil]; } - (NSFetchedResultsController *)fetchedResultsController { if (fetchedResultsController) return fetchedResultsController; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"FavoriteThing" inManagedObjectContext:managedObjectContext]; [fetchRequest setEntity:entity]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; NSNumber *yearBuscado = @2013; NSNumber *mesBuscado = @12; NSNumber *diaBuscado = @13; NSString *tipourgente = @"Urgent"; NSString *tipocolor = @"Yellow"; NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:@"todoYear == %@", yearBuscado]; NSPredicate *monthPredicate = [NSPredicate predicateWithFormat:@"todoMonth == %@", mesBuscado]; NSPredicate *dayPredicate = [NSPredicate predicateWithFormat:@"todoDay == %@", diaBuscado]; NSPredicate *urgentPredicate = [NSPredicate predicateWithFormat:@"urgent == %@", tipourgente]; NSPredicate *colorPredicate = [NSPredicate predicateWithFormat:@"color == %@", tipocolor]; [fetchRequest setSortDescriptors:sortDescriptors]; NSPredicate *busqueda = [NSCompoundPredicate andPredicateWithSubpredicates:@[yearPredicate, monthPredicate,dayPredicate,urgentPredicate]]; [fetchRequest setPredicate:busqueda]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil]; aFetchedResultsController.delegate = self; [self setFetchedResultsController:aFetchedResultsController]; [aFetchedResultsController release]; [fetchRequest release]; [sortDescriptor release]; [sortDescriptors release]; return fetchedResultsController; } - (void)dealloc { [fetchedResultsController release]; [managedObjectContext release]; [super dealloc]; } @end ```

Original source