开发者

Can you edit core data on ListViewController

I have a Core Data application set up with a ListViewController, a DetailViewController and an EditingViewController, where most of the editing occurs. On the ListViewController, I have a graphic of a checkbox, and I can toggle two images by selecting the row in

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

Is it possible to edit the Core Data record from the ListViewController so that I can make my selection persistent? I cannot work out the syntax to select the record, edit, and save the value - which will simply toggle from true to false.

jon

Thanks for the prompt response! Additional information after Answer 1. Your assumption is correct. I am modeling this application on the CoreData Books sample. I am not using a button, but rather using two images to create a checked and unchecked checkbox. I added a boolean "check" to my entity, recreated the header file, and added the header file to my ListViewController. Here is a simplified version of the datamodel header file.

@interface Patient :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString * lo开发者_运维问答cation;
@property (nonatomic, retain) NSNumber * check;
@property (nonatomic, retain) NSString * lastName;

@end

And here is my modification of your code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    NSManagedObject *entityObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
    if (![entityObject.check boolValue]) {
        entityObject.check = [NSNumber numberWithBool:YES];
        cell.imageView.image = [UIImage imageNamed:@"check.png"];
        }
    else {
        entityObject.check= [NSNumber numberWithBool:NO];
        cell.imageView.image = [UIImage imageNamed:@"uncheck.png"];
    }

However, this gives me the error "Request for member 'check' in something not a structure or union". I verified that the new attribute is a boolean and that the header file is imported to the ListViewController. Any thoughts?

Lastly, does this code eliminate the need to save entityObject.check to the database? Thanks again.


It would be nice to get a few more details about what your app does before we can provide a more informed recommendation. I'll make a few assumptions anyway to see if it helps...

Firstly, when dealing with BOOL properties in Coredata, it is important to remember that they are actually saved as NSNumbers so keep that in mind when you need to test their values and make sure you are using the right methods.

Assuming the data in your ListViewController is being populated by CoreData and your data model defines an entity "Entity" with an attribute of type BOOL called "favourite", here's what you can try:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

       NSManagedObject *entityObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
       if (![entityObject.favourite boolValue]) {
            entityObject.favourite = [NSNumber numberWithBool:YES];
            [self.yourToggleButton setSelected:YES]; // this assumes your checkbox is a UIButton and you want its view to be updated to checked when your BOOL == YES
        }
        else {
            entityObject.favourite = [NSNumber numberWithBool:NO];
            [self.watchListButton setSelected:NO];
        }

The above assumes you have a fetchedResultsController taking care of the data fetching from your CoreData database too. If not I strongly recommend you check out one the tutorials from Apple (CoreData Books and CoreData Recipes) to understand how they work as it will make your life much easier - NSFetchedResultsController make it pretty straight forward to keep your data syncronised between different views which is something you are going to have to consider specially because you are allowing different attributes to be edited in different view controllers.

I hope this helps but feel free to ask any additional questions if you need to. Cheers, Rog


I came up with a slightly different solution, but Rog's post definitely got me on the right track. I had some trouble with the boolean syntax, so I changed the entity attribute to a string and used "N" and "Y" instead. I also found that I needed to save the value to make it persistent. I appreciate the help.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Establish connections
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    Patient *patient = [self.fetchedResultsController objectAtIndexPath:indexPath];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    // Toggle images and check value with each row tap
    if ([patient.check isEqualToString: @"N"] == YES) {
        cell.imageView.image = [UIImage imageNamed:@"check.png"];
        patient.check = @"Y";
    }
    else {
        cell.imageView.image = [UIImage imageNamed:@"uncheck.png"];
        patient.check = @"N";
    }

    // Save check value
    NSError *error = nil;
    if (![context save:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜