Detectar qué UIButton se presionó en un UITableView

Resuelto rein asked hace 54 años • 26 respuestas

Tengo un UITableViewcon 5 UITableViewCells. Cada celda contiene un UIButtonque está configurado de la siguiente manera:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSString *identifier = @"identifier";
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
     if (cell == nil) {
         cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
         [cell autorelelase];

         UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
         [button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
         [button setTag:1];
         [cell.contentView addSubview:button];

         [button release];
     }

     UIButton *button = (UIButton *)[cell viewWithTag:1];
     [button setTitle:@"Edit" forState:UIControlStateNormal];

     return cell;
}

Mi pregunta es la siguiente: en el buttonPressedAction:método, ¿cómo sé qué botón se ha presionado? He considerado usar etiquetas, pero no estoy seguro de que sea la mejor ruta. Me gustaría poder etiquetar de alguna manera indexPathel control.

- (void)buttonPressedAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    // how do I know which button sent this message?
    // processing button press for this row requires an indexPath. 
}

¿Cuál es la forma estándar de hacer esto?

Editar:

Lo he resuelto haciendo lo siguiente. Todavía me gustaría tener una opinión sobre si esta es la forma estándar de hacerlo o si existe una forma mejor.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSString *identifier = @"identifier";
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
     if (cell == nil) {
         cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
         [cell autorelelase];

         UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
         [button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
         [cell.contentView addSubview:button];

         [button release];
     }

     UIButton *button = (UIButton *)[cell.contentView.subviews objectAtIndex:0];
     [button setTag:indexPath.row];
     [button setTitle:@"Edit" forState:UIControlStateNormal];

     return cell;
}

- (void)buttonPressedAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    int row = button.tag;
}

Lo que es importante tener en cuenta es que no puedo configurar la etiqueta en la creación de la celda ya que es posible que la celda se retire de la cola. Se siente muy sucio. Debe haber una mejor manera.

rein avatar Jan 01 '70 08:01 rein
Aceptado

En el ejemplo de accesorios de Apple se utiliza el siguiente método:

[button addTarget:self action:@selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside];

Luego, en el controlador táctil, se recupera la coordenada táctil y la ruta del índice se calcula a partir de esa coordenada:

- (void)checkButtonTapped:(id)sender
{
    CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
    if (indexPath != nil)
    {
     ...
    }
}
Vladimir avatar Nov 26 '2009 10:11 Vladimir

Descubrí que el método de usar la supervista de la supervista para obtener una referencia al indexPath de la celda funcionó perfectamente. Gracias a iphonedevbook.com (macnsmith) por el texto del enlace de sugerencia.

-(void)buttonPressed:(id)sender {
 UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
 NSIndexPath *clickedButtonPath = [self.tableView indexPathForCell:clickedCell];
...

}
Cocoanut avatar Jan 06 '2010 02:01 Cocoanut

Así es como lo hago. Sencillo y conciso:

- (IBAction)buttonTappedAction:(id)sender
{
    CGPoint buttonPosition = [sender convertPoint:CGPointZero
                                           toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
    ...
}
Chris Schwerdt avatar Sep 17 '2012 04:09 Chris Schwerdt