Question

I have a working app so far which basically consists of the following:

Using Core Data, I have 1 Table View Controller with an Add Button which modally calls up a new View Controller prompting the user to add text into three fields. There is also a selection field where the user has to choose between "bought" and "sold". When the user clicks save, the entry is added to the table view controller as a subtitle cell with the information filled in. It works well right now without the bought and sold aspect.

What I would like to do is simply change the color of the table view cell to be green for sold and red for bought. So when a user goes to add the information, they fill in the required fields and also choose bought or sold and then when clicking save, the table view cell displays either the green or red for each entry.

I am adding the tableView datasource and delegate methods here in the current TableViewController. With this, I am basically looking into a "Transaction" entity and fetching relationships to other Entities. The "Status" (Bought/Sold) is also in a related Entity to the Transaction Entity, in it's own entity called Purchase. So Transaction has a relationship called status.action (action being the inverse attribute to the Transaction).

Here's the code so far from the TableView:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.transactions.count;
}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Persons";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    NSManagedObject *transaction = [self.transactions objectAtIndex:indexPath.row];        
    [cell.textLabel setText:[NSString stringWithFormat:@"%@ %@", [transaction valueForKeyPath:@"whoBy.name"], [transaction valueForKeyPath:@"gifting.amount"]]];
    [cell.detailTextLabel setText:[NSString stringWithFormat:@"%@", [transaction valueForKeyPath:@"occasion.title"]]];

    return cell;        
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [self.managedObjectContext deleteObject:[self.transactions objectAtIndex:indexPath.row]];
        [self.transactions removeObjectAtIndex:indexPath.row];
        [self.tableView reloadData];

        NSError *error = nil;
        if (![self.managedObjectContext save:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
            [self.tableView reloadData];
        }
    }

}

The code from the Modal that actually goes ahead and allows the user to add the entries text (as well as select the Bought/Sold which is not implemented yet) looks like this:

NSManagedObjectContext *context = [self managedObjectContext];        
    NSManagedObject *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
    NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
    NSManagedObject *occasionEvent = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
    NSManagedObject *amountType = [NSEntityDescription insertNewObjectForEntityForName:@"Gift" inManagedObjectContext:context];
    [person setValue:self.nameTextField.text forKey:@"name"];
    [occasionEvent setValue:self.occasionTextField.text forKey:@"title"];
    [amountType setValue:self.amountTextField.text forKey:@"amount"]; 
    [transaction setValue:person forKey:@"whoBy"];
    [transaction setValue:occasionEvent forKey:@"occasion"];
    [transaction setValue:amountType forKey:@"gifting"]; 

Any help would be appreciated.

Thanks

Was it helpful?

Solution

Rather than trying to do this manually, all you need to do is read the state of the cell's object from the core data store and set the background colour appropriately.

I would also recommend using an NSFetchedResultsController as you datasource. It's designed to work well with Core Data and tableviews, and if you set up the delegates properly, it will even respond to changes in the model without any intervention from you.

edit

Following on from the comments you've added, I can see what the problem is.

Core Data stores objects not values. So when you try and put values into a core data store you turn them into objects first. And when you get the object out of core data you need to translate it into the value you want.

You can see this in what you are doing yourself when you add objects to your managed object:

 [transaction setValue:@(self.wasOptions.selectedSegmentIndex == 0) forKey:@"wasReceived"];

This expression returns a BOOL

self.wasOptions.selectedSegmentIndex == 0

A BOOl is a value and can't be stored into Core Data, so you turn it into an NSNumber representation with:

@(self.wasOptions.selectedSegmentIndex == 0)

So you now have an NSNumber object representing the BOOL value of YES or NO stored in core data.

When you try and get the value for your key:

 [transaction valueForKey:@"wasReceived"]

This is returning the NSNumber representation not the BOOL value it represents

In order to get the actual BOOL, use a convenient method from NSNumber boolValue. So to fix your problem replace this expression:

 [transaction valueForKey:@"wasReceived"]

with this expression:

[[transaction valueForKey:@"wasReceived"] boolValue]

which returns a proper BOOL value that your conditional can operate on.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top