質問

I use Core Data to keep track of entries in a simple to do list. I use a simple UIAlertView with UITextField for the user to add new entries. The entries are saved using NSManagedObject, but the latest entry isn't added to the tableview, even after I run [self.tableView reloadData];

This GIF show how it works now:

Header file:

#import <UIKit/UIKit.h>

@interface PakkelisteViewController : UITableViewController <UIAlertViewDelegate>

@end

Implementation file:

#import "PakkelisteViewController.h"
#import "AUFToDoItem.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];

    // defaultTodos = [[NSMutableArray alloc] initWithObjects:@"Badetøy", @"Skrivesaker", @"Lommepenger", @"Godt humør", nil];

    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
{
}

-(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:NO forKey:@"completed"];

        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 reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationFade];

//      [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";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }

    NSManagedObject *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];

    cell.textLabel.text = [toDoItem valueForKey:@"itemName"];

    if ((BOOL)[toDoItem valueForKey:@"completed"] == YES)
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else
    {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    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
役に立ちましたか?

解決

You need to add the new toDoItem to your array as well. Try this :

    // 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:NO forKey:@"completed"];

    [self.toDoItems addObject:toDoItem];
    [self.tableView reloadData];

他のヒント

You should update your dataSource self.toDoItems as it still stays the same as off in viewDidLoad method. You're only saving it in CoreData, but not refreshing your dataSourse and [tableView reloadData] wont do anything

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top