user1759949
user1759949

Reputation: 199

How do I get an edit button to work for a table view in xcode?

I've recently completed the apple tutorial on table views called Bird Watching and this worked fine. However, i'm now trying to take it further by adding an edit button and seem to be having a problem.

Below is the code that the MasterViewController uses to create my table. This works fine.

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

static NSDateFormatter *formatter = nil;
if(formatter == nil){
    formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

BirdSighting *sightingAtIndex = [self.dataController objectInListAtIndex:indexPath.row];
[[cell textLabel]setText:sightingAtIndex.name];
[[cell detailTextLabel]setText:[formatter stringFromDate:(NSDate *)sightingAtIndex.date]];
return cell;
}

I've tried using some of this code in order to get the edit button working and below is what I created. This doesn't work and I have no idea how to fix it.

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


if (editingStyle == UITableViewCellEditingStyleDelete) {
    BirdSighting *sightingAtIndex = [self.dataController removeObjectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
    // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}

One of the error messages I've had states "No visible @interface for BirdSightingDataController declares the selector removeObjectAtIndex.

Upvotes: 1

Views: 818

Answers (1)

Tim Vermeulen
Tim Vermeulen

Reputation: 12552

I looked up the Bird Watching tutorial on the Apple website, to know exactly what you're talking about and which classes the objects are an instance of.

In your tableView:commitEditingStyle:forRowAtIndexPath: method, you try to remove a certain object. When removing an object, you have to make sure it's deleted from both your view (in this case your table view) and your model object (in this case your data controller). Your removed the row from your table view like this:

[tableView deleteRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationFade];

This part looks good. However, you try to remove the object from your data controller using the following line of code:

BirdSighting *sightingAtIndex = [self.dataController removeObjectAtIndex:indexPath.row];

You sent the removeObjectAtIndex: method to self.dataController. The removeObjectAtIndex: method can only be sent to an instance of NSMutableArray. Your data controller is an instance of BirdSightingDataController, which is not an NSMutableArray. Thus, after trying to send the removeObjectAtIndex: method to self.dataController, you got an error.

To access the object at a certain index of your data controller array, you declared and implemented the objectInListAtIndex: method like this:

- (BirdSighting *)objectInListAtIndex:(NSUInteger)theIndex {
    return [self.masterBirdSightingList objectAtIndex:theIndex];
}

Now you want to remove the object at a certain index of your data controller array, you could declare a method like removeObjectInListAtIndex: in your BirdSightingDataController header file as well. You can then implement it like this:

- (void)removeObjectInListAtIndex:(NSUInteger)theIndex {
    [self.masterBirdSightingList removeObjectAtIndex:theIndex];
}

Note that this method doesn't return anything, as it just removes an object from the array. Make sure you use - (void) instead of - (BirdSighting *) in both your header and implementation file.

Now, instead of sending the removeObjectAtIndex: method to your data controller, you can simple remove the object (which the user deletes) from your data controller like this:

[self.dataController removeObjectInListAtIndex:indexPath.row];

Upvotes: 2

Related Questions