在UITableViewCell touch上更新核心数据对象

时间:2014-05-18 22:36:28

标签: ios objective-c core-data uitableview

我有一个简单的待办事项应用程序,用户可以触摸单元格来检查/取消选中任务。但我不知道如何更新Core Data将完成的布尔值设置为yes。

这是我的代码:

//     // PakkelisteViewController.m     // Sommerleir     //     //由Ronny-AndréBendiksen于08.05.14创建。     //版权所有(c)2014 Arbeidernes Ungdomsfylking。版权所有。     //

#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

2 个答案:

答案 0 :(得分:0)

变化:

tappedItem.completed = !tappedItem.completed;

为:

tappedItem.completed = @(![tappedItem.completed boolValue]);

这是在NSNumber实例中解压缩和重新打包bool值的最小代码。

此外,在您的if声明中,请勿检查BOOL值是否为== 1,因为这不一定是真的。只是说:

if ([tappedItem.completed]) { ...

您似乎也在使用的复选框图片的名称中输入错误。

答案 1 :(得分:0)

如果移动代码以更新tableView:tableView didSelectRowAtIndexPath:中的单元格状态,该怎么办?另外,你能用解释一下你的意思但我不知道如何更新Core Data设置完成的布尔值为是

在更新托管对象的状态后,使用save您正在使用的上下文,然后您可以在整个表或特定索引路径上执行重新加载。

BOOL hasTap = ![tappedItem.completed boolValue];
tappedItem.completed = @(hasTap); // or [NSNumber numberWithBool:hasTap];

// save

// reload

我真的关注乔纳森的评论。使用NSFetchedResultsController s(或UITableView s)对UICollectionView进行wotk。您可以设置其委托NSFetchedResultsControllerDelegate来监听和处理插入,删除,移动行(和部分)。

教程为Core Data Tutorial for iOS: How To Use NSFetchedResultsController