objective c - Obteniendo fila de celda UITableView al presionar un botón
objective-c ios (10)
Editar: esta respuesta está desactualizada. Por favor utiliza este método en su lugar
Prueba esto:
-(void)button1Tapped:(id)sender
{
UIButton *senderButton = (UIButton *)sender;
UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
UITableView* table = (UITableView *)[buttonCell superview];
NSIndexPath* pathOfTheCell = [table indexPathForCell:buttonCell];
NSInteger rowOfTheCell = [pathOfTheCell row];
NSLog(@"rowofthecell %d", rowOfTheCell);
}
Editar: si está usando contentView, use esto para buttonCell en su lugar:
UITableViewCell *buttonCell = (UITableViewCell *)senderButton.superview.superview;
Tengo un controlador de vista de tabla que muestra una fila de celdas. Cada celda tiene 3 botones. He numerado las etiquetas para cada celda para que sean 1,2,3. El problema es que no sé cómo buscar en qué celda se está presionando un botón. Actualmente solo obtengo la etiqueta del remitente cuando se presiona uno de los botones. ¿Hay alguna manera de obtener el número de fila de la celda también cuando se presiona un botón?
En rápido:
@IBAction func buttonAction(_ sender: UIButton) {
guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
return
}
// do something
}
Hay dos maneras:
@ H2CO3 tiene razón. Puede hacer lo que se sugirió @ user523234, pero con un pequeño cambio, para respetar el UITableViewCellContentView que debe aparecer entre UIButton y UITableViewCell. Entonces para modificar su código:
- (IBAction)button1Tapped:(id)sender { UIButton *senderButton = (UIButton *)sender; UITableViewCellContentView *cellContentView = (UITableViewCellContentView *)senderButton.superview; UITableViewCell *tableViewCell = (UITableViewCell *)cellContentView.superview; UITableView* tableView = (UITableView *)tableViewCell.superview; NSIndexPath* pathOfTheCell = [tableView indexPathForCell:tableViewCell]; NSInteger rowOfTheCell = pathOfTheCell.row; NSLog(@"rowofthecell %d", rowOfTheCell); }
Si crea una UITableViewCell personalizada (su propia subclase), puede simplemente llamar a
self
en IBAction. Puede vincular la función IBAction a su botón mediante el uso de guiones gráficos o mediante programación al configurar la celda.- (IBAction)button1Tapped:(id)sender { UITableView* tableView = (UITableView *)self.superview; NSIndexPath* pathOfTheCell = [tableView indexPathForCell:self]; NSInteger rowOfTheCell = pathOfTheCell.row; NSLog(@"rowofthecell %d", rowOfTheCell); }
Me gustaría compartir el código rápidamente -
extension UITableView
{
func indexPathForCellContainingView(view1:UIView?)->NSIndexPath?
{
var view = view1;
while view != nil {
if (view?.isKindOfClass(UITableViewCell) == true)
{
return self.indexPathForCell(view as! UITableViewCell)!
}
else
{
view = view?.superview;
}
}
return nil
}
}
Otra forma simple:
Obtenga el punto de contacto en tableView
A continuación, obtenga la ruta de índice de la celda en el punto
La ruta de índice contiene el índice de fila
El código es:
- (void)buttonTapped:(id)sender {
UITapGestureRecognizer *tap = (UITapGestureRecognizer *)sender;
CGPoint point = [tap locationInView:theTableView];
NSIndexPath *theIndexPath = [theTableView indexPathForRowAtPoint:point];
NSInteger theRowIndex = theIndexPath.row;
// do your stuff here
// ...
}
Realmente deberías estar usando este método:
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
Versión Swift:
let buttonPosition = sender.convert(CGPoint(), to:tableView)
let indexPath = tableView.indexPathForRow(at:buttonPosition)
Eso le dará el indexPath
basado en la posición del botón que se presionó. Luego, simplemente debe llamar a cellForRowAtIndexPath
si necesita la celda o indexPath.row
si necesita el número de fila.
Si está paranoico, puede verificar if (indexPath) ...
antes de usarlo, en caso de que indexPath
no se encuentre para ese punto en la vista de tabla.
Es probable que todas las otras respuestas se rompan si Apple decide cambiar la estructura de la vista.
Recomendaría esta forma de obtener indexPath de la celda que tiene una subvista personalizada ( compatible con iOS 7 y todas las versiones anteriores )
-(void)button1Tapped:(id)sender {
//- (void)cellSubviewTapped:(UIGestureRecognizer *)gestureRecognizer {
// UIView *parentCell = gestureRecognizer.view.superview;
UIView *parentCell = sender.superview;
while (![parentCell isKindOfClass:[UITableViewCell class]]) { // iOS 7 onwards the table cell hierachy has changed.
parentCell = parentCell.superview;
}
UIView *parentView = parentCell.superview;
while (![parentView isKindOfClass:[UITableView class]]) { // iOS 7 onwards the table cell hierachy has changed.
parentView = parentView.superview;
}
UITableView *tableView = (UITableView *)parentView;
NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)parentCell];
NSLog(@"indexPath = %@", indexPath);
}
Esto tampoco requiere self.tablview
.
Además, observe el código comentado que es útil si desea lo mismo a través de un @selector de UIGestureRecognizer agregado a su subvista personalizada.
Supongo que agregas botones a la celda en cellForRowAtIndexPath
, luego lo que haría es crear un UIButton
subclase de clase personalizado, agregar una etiqueta llamada rowNumber
y anexar esos datos mientras rowNumber
botón a la celda.
Una solución podría ser verificar la etiqueta de la vista superior del botón o incluso más arriba en la jerarquía de vista (si el botón está en la vista de contenido de la celda).
Swift 3
Nota: Esto debería ir realmente en la respuesta aceptada arriba, excepto que meta frunce el ceño ante tales ediciones.
@IBAction func doSomething(_ sender: UIButton) {
let buttonPosition = sender.convert(CGPoint(), to: tableView)
let index = tableView.indexPathForRow(at: buttonPosition)
}
Dos comentarios menores:
- La función predeterminada tiene el tipo de remitente como Cualquiera, que no tiene conversión.
- CGPointZero puede ser reemplazado por CGPoint ()