0

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.

Community
  • 1
  • 1
Scholle
  • 1,521
  • 2
  • 23
  • 44
  • Try adding the button to the cell itself, and not the UIImageView. – gdavis Nov 21 '12 at 15:42
  • Sure, this works, but I need to add the buttons to some kind of view in order to be able to slide a group of buttons out of the visible area, e.g. when the users swipes over the table cell to disclose a sub menu. – Scholle Nov 21 '12 at 16:19

1 Answers1

0

UIImageViews don't have user interaction enabled. You should be adding it to the cell itself, or another UIView.

gdavis
  • 2,556
  • 1
  • 20
  • 25
  • Ok, but what kind of view to use instead? As I said, I replaced UIImageView with UIControl and also UIView. It all works, but then, all UITableViewDelegate methods, e.g. the cellForRowAtIndexPath method, don't get called. – Scholle Nov 21 '12 at 16:22
  • 1
    Right, both won't get called. The button is stopping the touch event from reaching the cell because of the way it captures touch events. If you want both to happen, you might need stop using UIButtons, and instead use the touchesBegan: and touchesEnded: methods to do some hit testing on your button to to react to both. And don't forget to call the `super` implementations of those methods to keep the table interactions working. – gdavis Nov 21 '12 at 20:22