Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a delegate to a custom UITableViewCell (bad access error)

I'm trying to add a custom delegate to a custom UITableViewCell of mine.

On this cell I have a button which need to fire a method in the ViewController where the UITableView is located on.

I'm doing all the usual steps to add a custom delegate but for some reason when I open the VC on runtime the app crashes and gives me a bad access error.

When I comment all the delegate code it works properly so my guess is that something is wrong the way I add my delegate. When I leave my id property uncommented it seems to crash.

I implement the protocol in the VC. I did assign the delegate to the cell in the cellForRowAtIndexPath:. All the delegate methods are in place. I've been using similar constructions in other classes but never in a subclass of UITableViewCells before.

Before I post some code I would like to know if someone encountered this bug before. If and how he solved it or if it is even possible to make a custom delegate for an UITableViewCell subclass.


EDIT:

My customCell.h

#import <UIKit/UIKit.h>

@class MyTableViewCell;

@protocol MyTableCellProtocoll <NSObject>

-(void) didPressButton:(MyTableViewCell *)theCell;

@end

@interface MyTableViewCell : UITableViewCell
{

    UIButton *myButton;

    id<MyTableCellProtocoll> delegationListener;

}

@property (nonatomic,retain) UIButton *myButton;

@property (nonatomic,assign) id<MyTableCellProtocoll> delegationListener;

- (void) buttonAction;

@end

.m

#import "MyTableViewCell.h"

@implementation MyTableViewCell

@synthesize myButton;
@synthesize delegationListener;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code

        self.myButton = [UIButton buttonWithType:UIButtonTypeCustom];
        self.myButton.backgroundColor = [UIColor clearColor];
        self.myButton.frame = CGRectMake(5, 0, 10, 32);
        self.myButton.titleLabel.adjustsFontSizeToFitWidth = YES;
        [self.myButton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:self.myButton];  
    }
    return self;
}

- (void) buttonAction
{
    NSLog(@"buttonpressed");
    [self.delegationListener didPressButton:self];
}

@end

MyVC implements the delegate as proper in the .h

@interface MyVC : UIViewController <UITableViewDelegate, UITableViewDataSource, MyTableCellProtocoll>

and it also uses the one delegatemethod from MyTableCellProtocoll in the .m

- (void)didPressButton:(MyTableViewCell *)theCell
{
    NSLog(@"didPressButton");
}

I assign the delegate in the cellForRowAtIndexPath:

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

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.delegationListener = self;
    }

    return cell;
}

These are all locations I use for the delegate. What I want it to do is change the buttontitle and insert some rows after that cell (modified duplicates)

Hope this will clear things up a bit more.


EDIT2: The button method is not being called at start as was metioned in the comment section. Editted code with logcode.


EDIT3: There is nothing wrong with the button. It is the delegate property that is messed up somewhere. With breakpoints and logs and commenting i made sure of that.

The code is being run up to the last element in my datasource list then it crashes. 1 step closer to the problem now i suppose.


FINAL EDIT: Ok, it seems like all of the delegates and buttons and other components weren't the problem at all. It was the heightForRowAtIndexPath: screwing me over. Thanks for all of your support anyhow!

like image 243
Totumus Maximus Avatar asked Nov 09 '11 09:11

Totumus Maximus


3 Answers

I have heard that synthesized accessors should not be used during init. Try to do all the setup code using the ivars directly:

myButton = [[UIButton alloc] init];         
myButton.backgroundColor = [UIColor clearColor];         
myButton.frame = CGRectMake(5, 0, 10, 32);         myButton.titleLabel.adjustsFontSizeToFitWidth = YES;         
[myButton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];         
[contentView addSubview:myButton];

If you change your button creation to [UIButton buttonWithType:UIButtonTypeCustom]; as beryllium rightly suggests, then you will also need to retain it.

like image 191
jrturton Avatar answered Nov 15 '22 20:11

jrturton


This question has been solved. The problem wasn't in the delegate and unrelated to the button issues in the other answers. The problem was lying in the access of a cell in the heightForRowAtIndexpath: and was easily solved once figured out.

I was kindly pointed to the right direction by jrturton and for this he has my thanks.

like image 37
Totumus Maximus Avatar answered Nov 15 '22 22:11

Totumus Maximus


At first your interface called MyTableViewCell, implementation - iPadCheckTableViewCell. I think both should have the same name.

And create button like this:

self.myButton = [UIButton buttonWithType:UIButtonTypeCustom]; // instead of self.myButton = [[UIButton alloc] init]; - it's a memory leak
like image 36
beryllium Avatar answered Nov 15 '22 20:11

beryllium