0

I have a UITableView with custom table view cell.

That cell has a custom delete button. Button action is within the cell class.

I can't reload the table from cell class after deleted row from db. If I try to get table view from cell.superview or cell.superview.superview, the app crashes.

This is cell implementation

@implementation pixSavedTableViewCell

- (IBAction)deleteBusiness:(id)sender {
    NSLog(@"DELETING BUSINESS cell");
    self.hidden=YES;
    pixDBManager *dbConnection = [[pixDBManager alloc]init];
    dbConnection.businessName = self.nameLable.text;
    [dbConnection deleteBusiness];
    //[(UITableView *)self.superview.superview reloadData];
}
@end

This will delete data from

-(void)deleteBusiness
{
    NSLog(@"DELETING BUSINESS");
    char *error;
    if(sqlite3_open([dbPathString UTF8String], &businessDB)==SQLITE_OK){
        NSString *deleteStatement = [NSString stringWithFormat:@"DELETE FROM SAVEDBUSINESS      WHERE 'NAME'='%@'",_businessName];
        const char *delete_stmt = [deleteStatement UTF8String];
        NSLog(@"%s",delete_stmt);
        if (sqlite3_exec(businessDB, delete_stmt, NULL, NULL, &error)==SQLITE_OK) {
            NSLog(@"Business Deleted");

        }
        else{
            NSLog(@"Cant Delete Data");
        }
        sqlite3_close(businessDB);
    }
    else{
        NSLog(@"Cant Open Data Base");
    }
}

This is my view controller implementation

@implementation pixSavedViewController
{
    NSMutableArray *businessArray;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    pixDBManager *dbConnection = [[pixDBManager alloc]init];
    businessArray = [[NSMutableArray alloc]init];
    [dbConnection createOrOpenDB];
    businessArray = [dbConnection getSavedBusiness];
    // Do any additional setup after loading the view.
}

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

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

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

    pixSavedTableViewCell *cell = (pixSavedTableViewCell *)[tableView   dequeueReusableCellWithIdentifier:customcellidentifier];

    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"Savedcell" owner:self options:nil];
        cell = [nib objectAtIndex:0];

    }
    pixBusinessDetails *details = [[pixBusinessDetails alloc]init];
    details = [businessArray objectAtIndex:indexPath.row];
    cell.nameLable.text = details.name;
    cell.addressLable.text = details.address;
    cell.descriptionLable.text = details.description;
    cell.scoreLable.text = details.score;
    cell.votesLable.text = details.votes;
    NSLog(@"Business Detail %@\n %@\n %@\n %@\n %@\n %@\n",details.name, details.address,details.description,details.score,details.votes,details.imageId);

    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{     
    return 130;
}
Siva777
  • 35
  • 9
  • I think your issue is the way you're trying to get the superview. You cannot make the assumption that the cells superview is the tableview. Instead you need to traverse the hierarchy until its found. See this answer for help. http://stackoverflow.com/questions/15711645/how-to-get-uitableview-from-uitableviewcell – Freddy Jul 09 '14 at 11:58
  • If you have a question, I would ask that instead of just posting code and telling us what is wrong with it. – Pseudonym Jul 09 '14 at 12:06
  • What you're trying to do is like killing yourself and pretending to clean up the mess after you're already dead xD – maganap Jul 08 '16 at 08:40

2 Answers2

4

Rather than deleting the data from within the UITableViewCell, you should instead call a method in your UIViewController which will delete the data and then reload the table.

On way to do this is to create a protocol for your UIViewController to conform to:

@protocol pixSavedTableViewCellDelegate
- (void)deleteBuisness:(NSString *) businessName
@end

@interface pixSavedTableViewCell : UITableViewCell
@property (nonatomic, weak) id<pixSavedTableViewCellDelegate> delegate;
@end

Then in you UITableViewCell you change your delete method to:

- (IBAction)deleteBusiness:(id)sender {
    [self.delegate deleteBuisness:self.nameLabel.text];
}

In your UIViewController you then implement the protocol:

@interface pixSavedViewController <pixSavedTableViewCellDelegate>
@end

@implementation pixSavedViewController
#pragma mark - pixSavedTableViewCellDelegate
- (void)deleteBuisness:(NSString *) businessName
{
    pixDBManager *dbConnection = [[pixDBManager alloc]init];
    dbConnection.businessName = businessName;
    [dbConnection deleteBusiness];

    [self.tableView reloadData];
}

You'll also need to set the delegate when creating the cell:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath      *)indexPath
{
    //All your current code
    cell.delegate = self;

    return cell;
}
Karl Monaghan
  • 880
  • 9
  • 14
  • Nice Approach. Good one – Kumar KL Jul 09 '14 at 12:15
  • - (IBAction)deleteBusiness:(id)sender { NSLog(@"Deleting"); [self.delegate deleteBuisness:self.nameLable.text]; } @end This function not executing...... – Siva777 Jul 09 '14 at 12:40
  • 1
    Did you set the delegate? – Karl Monaghan Jul 09 '14 at 13:05
  • Set a breakpoint in the method and make sure self.delegate is not nil. I presume you also made the all changes to your UIViewController? – Karl Monaghan Jul 09 '14 at 13:16
  • Sorry karl i confused, It executed upto [dbConnection deleteBusiness]; but didnt worked [self.tableView reloadData]; – Siva777 Jul 09 '14 at 16:15
  • Well is self.tableView the same name as your `UITableView` property? Is an error thrown? – Karl Monaghan Jul 09 '14 at 19:33
  • Yes @property (weak, nonatomic) IBOutlet UITableView *tableView; – Siva777 Jul 10 '14 at 04:52
  • Hey karl that is my mistake,Your answer is correct i forgot to reallocate the datasourse array. now i added businessArray = [[NSMutableArray alloc]init]; businessArray = [dbConnection getSavedBusiness];. Now its worked perfectly what how i expect. Thanx very very thanx :). This is my first question in stack overflow. – Siva777 Jul 10 '14 at 05:03
2

This is what the delegate pattern is for, in my opinion:

Make your UITableViewController a delegate of your custom cell.

MyCustomCell *cell = ....
cell.deleteDelegate = self

//in your UITableViewController
- (void)willDeleteCustomCell:(MyCustomCell*)cell
{

}

//on your cell
- (IBAction)deleteBusiness:(id)sender
{
     [self.deleteDelegate willDeleteCustomCell:self];

     //rest of your delete code
}
Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100
  • I did this but - (IBAction)deleteBusiness:(id)sender this function not executing... – Siva777 Jul 09 '14 at 12:43
  • I was under the assumption that this method was already connected correctly in your project. What did you do to make it stop working? – Adam Jenkins Jul 09 '14 at 12:53
  • yes this method connected correctly... i added NSLog to that method. And i ran the app.it didnt executed NSlog. when i remove [self.deleteDelegate willDeleteCustomCell:self] method, it executed NSlog.. – Siva777 Jul 09 '14 at 13:00
  • I don't understand. If you add an `NSLog` after the line `[self.deleteDelegate willDeleteCustomCell:self]` and the `NSLog` doesn't get executed, then I assume your app must crash? The simple presence of a line inside a method will not prevent that method from getting executed. – Adam Jenkins Jul 09 '14 at 13:04
  • Thats exactly happened...i added NSLog before [self.deleteDelegate willDeleteCustomCell:self] and The simple presence of a line inside a method did prevent that method from getting executed – Siva777 Jul 09 '14 at 13:13
  • I can't imagine any scenario where that is logical. – Adam Jenkins Jul 09 '14 at 13:18
  • No I cannot. You should post your current relevant code which is your cell and your view controller. – Adam Jenkins Jul 09 '14 at 13:48
  • Adam this answer also correct but i cant accept two answer in a question. thanx very much.. – Siva777 Jul 10 '14 at 05:06