There are some discussions on how to add a UIButton to a UITableCellView in the famous
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
method and on how to handle button clicks. I have tested them and they all more or less work fine.
I have slightly different setup. I want to add the UIButton - in fact I have several buttons positioned on different UIImageViews - hided/shown using swipe touches, within my custom UITableCellView class. To keep things simple, let's assume there is only one UIImageView added to the cell's view stack and one UIButton only:
This is the relevant part of my UITableViewCell implementation:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// sub menu
self.tableCellSubMenu = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320.0, 88.0)];
[self.tableCellSubMenu setImage:[UIImage imageNamed:@"cell_menu_back"]];
[self addSubview:self.tableCellSubMenu];
UIButton *but = [UIButton buttonWithType:UIButtonTypeCustom];
but.frame = CGRectMake(10.0, 0, 77.0, 88.0);
[but setImage:[UIImage imageNamed:@"cell_menu_icon_plus_up"] forState:UIControlStateNormal];
[but setImage:[UIImage imageNamed:@"cell_menu_icon_plus_down"] forState:UIControlStateSelected];
[but setImage:[UIImage imageNamed:@"cell_menu_icon_plus_down"] forState:UIControlStateHighlighted];
[but addTarget:self action:@selector(tableCellButtonPress:) forControlEvents:UIControlEventTouchUpInside];
[self.tableCellSubMenu addSubview:but];
...
}
return self;
}
The UIButton is added to an UIImageView, which in turn as added to the cell's view stack. For simplicity, I configured the target for the button to "self". In my real setup, the target is the UITableViewController where I handle the button events. I can guarantee that all the setup is working (e.g. by replacing UIImageView with UIControl, as we see later).
Unfortunately, in this configuration, a touch up inside event on the button doesn't fire. The only function which gets called is
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
in the controller. Usually, I place UIButtons on a UIControl view. Having said that, when I replace UIImageView with UIControl in the above code, the button event fires as expected, but then,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
doesn't get called anymore. I want both.
How to get this to work?
Update 1:
I have implemented the following method in my custom UITableViewCell implementation:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint location = [((UITouch *)[touches anyObject]) locationInView:self];
if (CGRectContainsPoint(but.frame, location)) {
[self.touchButtonDelegate tableViewCellButtonTouched:self button:(UIButton*)but indexPath:self.touchButtonIndexPath];
}
[super touchesBegan:touches withEvent:event];
}
I am still using "UIImageView" to group and position several buttons.
The self.touchButtonDelegate is the UITableViewController. A more complete solution is available here.