Question

I'm just practicing with UITableView. Here is what I did so far.

  • made cells with xib.file from scratch.
  • Data is stored in P-list.
  • Using [ MutableCopy] and convert array into mutableArray
  • It looks little strange but I made the delegate connection using storyboard ,so there's no "self.tableView.delegate = self" line here.

Now the problem is I can delete the objects in the mutableArray but not on UI. The row I selected is remained on the table. I know "- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath" delegation method works but something goes wrong.

Any Advice is appreciated! Thanks:)

![#import "ViewController.h"
#import "Model.h"
#import "SimpleTableCell.h"

@interface ViewController ()
{

    NSMutableArray *_recipesMC;
    NSMutableArray *_imagesMC;

    Model *_model;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
    \[super viewDidLoad\];
    // Do any additional setup after loading the view, typically from a nib.

    Model *model = \[\[Model alloc\] init\];
    \[model getBack\];

    NSArray *recipes = model.recipes;
    NSArray *images = model.imagesArray;

    _recipesMC = \[recipes mutableCopy\];
    _imagesMC = \[images mutableCopy\];


}

- (void)didReceiveMemoryWarning
{
    \[super didReceiveMemoryWarning\];
    // Dispose of any resources that can be recreated.
}



# pragma mark delegat patern


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return \[_recipesMC count\];

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSString *cellIdentifier = @"SimpleTableCell";


    SimpleTableCell *cell = (SimpleTableCell *)\[tableView dequeueReusableCellWithIdentifier:cellIdentifier\];


    if(cell == nil)
    {

        NSArray *nib = \[\[NSBundle mainBundle\] loadNibNamed:@"Empty" owner:self options:nil\];
        cell = \[nib objectAtIndex:0\];

    }

    cell.nameLabel.text = \[_recipesMC objectAtIndex:indexPath.row\];

    if (indexPath.row < \[_recipesMC count\] - 1)
    {
        UIImage *image = \[UIImage imageNamed:_imagesMC\[indexPath.row\]\];
        cell.thumbnailImageView.image = image;

    }


    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 78;

}


# pragma mark delegate touch


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"%li",(long)indexPath.row);

    UIAlertView *alert = \[\[UIAlertView alloc\] initWithTitle:@"HEY" message:\[NSString stringWithFormat:@"%@",_recipesMC\[indexPath.row\]\] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil\];
    \[alert show\];

    UITableViewCell *cell = \[tableView cellForRowAtIndexPath:indexPath\];

    if (cell.accessoryType !=
        UITableViewCellAccessoryNone) {


        cell.accessoryType =
        UITableViewCellAccessoryNone;

    }
    else
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }


    \[self performSegueWithIdentifier:@"CellSelectionSegue" sender:self\];

}



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

    NSLog(@"Clicked DELETE BUTTON at %i",indexPath.row);

    \[_recipesMC removeObjectAtIndex:indexPath.row\];
    \[_imagesMC removeObjectAtIndex:indexPath.row\];

    \[self.tableView reloadData\];

    NSLog(@"count = %i",\[_recipesMC count\]);

}



# pragma mark Segue

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSLog(@"Segue");
}


@end
Was it helpful?

Solution

I'm pretty sure your self.tableView is nil.

It's because even if you set self as datasource and delegate, your table will work, but here you seems to have create your UITableView *tableView but didn't link it through your interface (if you do it with the builder).

Or you can simply call tableView rather than self.tableView because the delegate protocole gives you the table.

Just do it and it will work. And then, you can try the solution of Szu.

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

    NSLog(@"Clicked DELETE BUTTON at %i",indexPath.row);

    [_recipesMC removeObjectAtIndex:indexPath.row];
    [_imagesMC removeObjectAtIndex:indexPath.row];

    [tableView reloadData];

    NSLog(@"count = %i",[_recipesMC count]);

}

OTHER TIPS

Yo should call deleteRowsAtIndexPath:wothRowAnimation:

e.g. in my code:

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        ElKeyValuePair *pair = [self.locationFavoritesKeyArr objectAtIndex:[indexPath row]];
        [self.locationFavoritesKeyArr removeObjectAtIndex:[indexPath row]];
        ELCarpark *carpark = [self.agglomeration carparkForUid:[pair.val1 intValue]];
        [carpark removeFromFavoritesAgglomerationUid:self.agglomeration.uid];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }

Adding this code to the method tableView:commitEditingStyle:forRowAtIndexPath should remove the row from the data source and the UI.

if (editingStyle == UITableViewCellEditingStyleDelete)
{
[_recipesMC removeObjectAtIndex:indexPath.row];
[_imagesMC removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:indexPath withRowAnimation:YES];
}

Finally remove the reloadData instruction.

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