uitableviewcontroller uitableviewcell example iphone uitableview

iphone - uitableviewcell - Detectar qué UIButton fue presionado en un UITableView



uitableviewcontroller (26)

¿Me estoy perdiendo de algo? ¿No puedes usar el remitente para identificar el botón? El remitente le dará información como esta:

<UIButton: 0x4b95c10; frame = (246 26; 30 30); opaque = NO; tag = 104; layer = <CALayer: 0x4b95be0>>

Luego, si desea cambiar las propiedades del botón, diga la imagen de fondo que acaba de decirle al remitente:

[sender setBackgroundImage:[UIImage imageNamed:@"new-image.png"] forState:UIControlStateNormal];

Si necesita la etiqueta, entonces el método de ACBurk está bien.

Tengo un UITableView con 5 UITableViewCells . Cada celda contiene un UIButton que se configura 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 método buttonPressedAction: ¿cómo puedo saber qué botón se ha presionado? He considerado usar etiquetas, pero no estoy seguro de que esta sea la mejor ruta. Me gustaría poder etiquetar de alguna manera el indexPath en el 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 un poco haciendo lo siguiente. Todavía me gustaría tener una opinión sobre si esta es la forma estándar de hacerlo o si hay una manera 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 establecer la etiqueta en la creación de la celda ya que la celda podría ser eliminada de la cola. Se siente muy sucio. Tiene que haber una mejor manera.


¿Qué hay de enviar la información como NSIndexPath en el UIButton usando inyección de tiempo de ejecución.

1) Necesitas runtime en la importación.

2) agregar constante estática

3) agregue NSIndexPath a su botón en tiempo de ejecución usando:

(void) setMetaData: (id) target withObject: (id) newObj

4) en el botón presione obtener metadatos usando:

(id) metaData: (id) target

Disfrutar

#import <objc/runtime.h> static char const * const kMetaDic = "kMetaDic"; #pragma mark - Getters / Setters - (id)metaData:(id)target { return objc_getAssociatedObject(target, kMetaDic); } - (void)setMetaData:(id)target withObject:(id)newObj { objc_setAssociatedObject(target, kMetaDic, newObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #On the cell constructor - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { .... cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; .... [btnSocial addTarget:self action:@selector(openComments:) forControlEvents:UIControlEventTouchUpInside]; #add the indexpath here or another object [self setMetaData:btnSocial withObject:indexPath]; .... } #The action after button been press: - (IBAction)openComments:(UIButton*)sender{ NSIndexPath *indexPath = [self metaData:sender]; NSLog(@"indexPath: %d", indexPath.row); //Reuse your indexpath Now }


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]; ...


Aunque me gusta la forma de la etiqueta ... si no quieres usar etiquetas por cualquier razón, puedes crear un miembro NSArray de botones prefabricados:

NSArray* buttons ;

a continuación, cree esos botones antes de representar la vista de tabla y empújelos en la matriz.

Luego, dentro de la función tableView:cellForRowAtIndexPath: puede hacer:

UIButton* button = [buttons objectAtIndex:[indexPath row] ] ; [cell.contentView addSubview:button];

Luego en la función buttonPressedAction: puedes hacer

- (void)buttonPressedAction:(id)sender { UIButton* button = (UIButton*)sender ; int row = [buttons indexOfObject:button] ; // Do magic }


Con Swift 4.2 y iOS 12, UITableView tiene un método llamado indexPathForRow(at:) . indexPathForRow(at:) tiene la siguiente declaración:

func indexPathForRow(at point: CGPoint) -> IndexPath?

Devuelve una ruta de índice que identifica la fila y la sección en el punto dado.

El siguiente código completo muestra cómo implementar indexPathForRow(at:) para obtener el IndexPath correspondiente de un UIButton ubicado en un UITableViewCell :

import UIKit class CustomCell: UITableViewCell { let button = UIButton(type: .system) override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) button.setTitle("Tap", for: .normal) contentView.addSubview(button) button.translatesAutoresizingMaskIntoConstraints = false button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true button.topAnchor.constraintEqualToSystemSpacingBelow(contentView.topAnchor, multiplier: 1).isActive = true button.leadingAnchor.constraintGreaterThanOrEqualToSystemSpacingAfter(contentView.leadingAnchor, multiplier: 1).isActive = true } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }

import UIKit class TableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() tableView.register(CustomCell.self, forCellReuseIdentifier: "Cell") } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 3 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell cell.button.addTarget(self, action: #selector(printIndexPath), for: .touchUpInside) return cell } @objc func printIndexPath(_ sender: UIButton) { let point = sender.convert(CGPoint.zero, to: tableView) guard let indexPath = tableView.indexPathForRow(at: point) else { return } print(indexPath) } }


En la muestra de Accessory de Apple se usa el siguiente método:

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

Luego, en el controlador táctil, las coordenadas táctiles recuperadas y la ruta del índice se calculan 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) { ... } }


Encontré que el método de usar la supervisión de supervisión para obtener una referencia a la indexPath de la celda funcionó perfectamente. Gracias a iphonedevbook.com (macnsmith) por el texto del enlace de sugerencias

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


Encontré una buena solución para este problema en otro lugar, sin perder el tiempo con las etiquetas en el botón:

- (void)buttonPressedAction:(id)sender { NSSet *touches = [event allTouches]; UITouch *touch = [touches anyObject]; CGPoint currentTouchPosition = [touch locationInView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition]; do stuff with the indexPath... }


Es sencillo; Haz una celda personalizada y saca una salida de botón.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *identifier = @"identifier"; customCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; cell.yourButton.tag = indexPath.Row; - (void)buttonPressedAction:(id)sender

cambiar id en el método anterior a (UIButton *)

Puede obtener el valor que el botón se está tocando haciendo sender.tag.


Este problema tiene dos partes:

1) Obtención de la ruta de índice de UITableViewCell que contiene UIButton presionado

Hay algunas sugerencias como:

  • Actualización de la tag de cellForRowAtIndexPath: en cellForRowAtIndexPath: método que utiliza el valor de row la ruta del índice. Esta no es una buena solución ya que requiere actualizar la tag continuamente y no funciona con vistas de tabla con más de una sección.

  • Agregar una propiedad NSIndexPath a una celda personalizada y actualizarla en lugar de la tag de cellForRowAtIndexPath: en cellForRowAtIndexPath: método. Esto resuelve el problema de varias secciones, pero aún no es bueno, ya que requiere una actualización siempre.

  • Manteniendo una breve referencia a UITableView principal en la celda personalizada mientras la creamos y indexPathForCell: método indexPathForCell: para obtener la ruta del índice. Parece un poco mejor, no es necesario actualizar nada en el método cellForRowAtIndexPath: pero aún así es necesario establecer una referencia débil cuando se crea la celda personalizada.

  • Usando la propiedad superView la superView para obtener una referencia al UITableView padre. No es necesario agregar ninguna propiedad a la celda personalizada, y no es necesario configurar / actualizar nada en la creación / más adelante. Pero el superView la superView depende de los detalles de implementación de iOS. Por lo que no se puede utilizar directamente.

Pero esto se puede lograr utilizando un bucle simple, ya que estamos seguros de que la celda en cuestión debe estar en un UITableView:

UIView* view = self; while (view && ![view isKindOfClass:UITableView.class]) view = view.superview; UITableView* parentTableView = (UITableView*)view;

Por lo tanto, estas sugerencias se pueden combinar en un método de celda personalizado simple y seguro para obtener la ruta del índice:

- (NSIndexPath *)indexPath { UIView* view = self; while (view && ![view isKindOfClass:UITableView.class]) view = view.superview; return [(UITableView*)view indexPathForCell:self]; }

A partir de ahora, este método se puede utilizar para detectar qué UIButton se presiona.

2) Informar a otras partes sobre el evento de presionar botones

Después de saber internamente qué UIButton se presiona en qué celda personalizada con la ruta de índice exacta, esta información debe enviarse a otras partes (lo más probable es que el controlador de vista que maneja el UITableView ). Por lo tanto, este evento de clic de botón se puede manejar en un nivel lógico y de abstracción similar al método didSelectRowAtIndexPath: del delegado UITableView.

Se pueden utilizar dos enfoques para esto:

a) Delegación: la celda personalizada puede tener una propiedad de delegate y puede definir un protocolo. Cuando se presiona el botón, simplemente ejecuta sus métodos de delegado en su propiedad de delegate . Pero esta propiedad delegate debe establecerse para cada celda personalizada cuando se crean. Como alternativa, la celda personalizada también puede optar por realizar sus métodos de delegado en su delegado de la vista de tabla principal.

b) Centro de notificaciones: las celdas personalizadas pueden definir un nombre de notificación personalizado y publicar esta notificación con la ruta del índice y la información de vista de la tabla principal proporcionada en el objeto userInfo . No es necesario configurar nada para cada celda, basta con agregar un observador para la notificación de la celda personalizada.


Funciona para mí también, gracias @Cocoanut

Encontré que el método de usar la supervisión de supervisión para obtener una referencia a la indexPath de la celda funcionó perfectamente. Gracias a iphonedevbook.com (macnsmith) por el texto del enlace de sugerencias

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


La respuesta de do do (@Vladimir) es Swift:

var buttonPosition = sender.convertPoint(CGPointZero, toView: self.tableView) var indexPath = self.tableView.indexPathForRowAtPoint(buttonPosition)!

Aunque la comprobación de indexPath != nil me da el dedo ... "NSIndexPath no es un subtipo de NSString"


La solución de Chris Schwerdt, pero luego en Swift trabajó para mí:

@IBAction func rateButtonTapped(sender: UIButton) { let buttonPosition : CGPoint = sender.convertPoint(CGPointZero, toView: self.ratingTableView) let indexPath : NSIndexPath = self.ratingTableView.indexPathForRowAtPoint(buttonPosition)! print(sender.tag) print(indexPath.row) }


PARA MANEJAR SECCIONES - Almacené NSIndexPath en un UITableViewCell personalizado

EN CLKIndexPricesHEADERTableViewCell.xib

EN IB Añadir UIButton a XIB - ¡NO añada acción!

Agregar outlet @property (retener, no atómico) IBOutlet UIButton * buttonIndexSectionClose;

NO CTRL + DRAG una acción en IB (hecho en el código de abajo)

@interface CLKIndexPricesHEADERTableViewCell : UITableViewCell ... @property (retain, nonatomic) IBOutlet UIButton *buttonIndexSectionClose; @property (nonatomic, retain) NSIndexPath * indexPathForCell; @end

En viewForHeaderInSection (también debería funcionar para cellForRow .... etc si la tabla tiene solo 1 sección)

- viewForHeaderInSection is called for each section 1...2...3 - get the cell CLKIndexPricesHEADERTableViewCell - getTableRowHEADER just does the normal dequeueReusableCellWithIdentifier - STORE the indexPath IN the UITableView cell - indexPath.section = (NSInteger)section - indexPath.row = 0 always (we are only interested in sections) - (UIView *) tableView:(UITableView *)tableView1 viewForHeaderInSection:(NSInteger)section { //Standard method for getting a UITableViewCell CLKIndexPricesHEADERTableViewCell * cellHEADER = [self getTableRowHEADER];

... usa la sección para obtener datos para tu celular

...rellenarlo

indexName = ffaIndex.routeCode; indexPrice = ffaIndex.indexValue; // [cellHEADER.buttonIndexSectionClose addTarget:self action:@selector(buttonDELETEINDEXPressedAction:forEvent:) forControlEvents:UIControlEventTouchUpInside]; cellHEADER.indexPathForCell = [NSIndexPath indexPathForRow:0 inSection:section]; return cellHEADER; }

El USUARIO presiona el botón DELETE en el encabezado de una Sección y esto llama

- (void)buttonDELETEINDEXPressedAction:(id)sender forEvent:(UIEvent *)event { NSLog(@"%s", __PRETTY_FUNCTION__); UIView * parent1 = [sender superview]; // UiTableViewCellContentView //UIView *myContentView = (UIView *)parent1; UIView * parent2 = [parent1 superview]; // custom cell containing the content view //UIView * parent3 = [parent2 superview]; // UITableView containing the cell //UIView * parent4 = [parent3 superview]; // UIView containing the table if([parent2 isMemberOfClass:[CLKIndexPricesHEADERTableViewCell class]]){ CLKIndexPricesHEADERTableViewCell *myTableCell = (CLKIndexPricesHEADERTableViewCell *)parent2; //UITableView *myTable = (UITableView *)parent3; //UIView *mainView = (UIView *)parent4; NSLog(@"%s indexPath.section,row[%d,%d]", __PRETTY_FUNCTION__, myTableCell.indexPathForCell.section,myTableCell.indexPathForCell.row); NSString *key = [self.sortedKeysArray objectAtIndex:myTableCell.indexPathForCell.section]; if(key){ NSLog(@"%s DELETE object at key:%@", __PRETTY_FUNCTION__,key); self.keyForSectionIndexToDelete = key; self.sectionIndexToDelete = myTableCell.indexPathForCell.section; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Remove Index" message:@"Are you sure" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil]; alertView.tag = kALERTVIEW_REMOVE_ONE_INDEX; [alertView show]; [alertView release]; //------ }else{ NSLog(@"ERROR: [%s] key is nil for section:%d", __PRETTY_FUNCTION__,myTableCell.indexPathForCell.section); } }else{ NSLog(@"ERROR: [%s] CLKIndexPricesHEADERTableViewCell not found", __PRETTY_FUNCTION__); } }

En este ejemplo, agregué un botón Eliminar, por lo que debería mostrar UIAlertView para confirmarlo.

Almaceno la sección y la clave en el diccionario que almacena información sobre la sección en un ivar en la CV

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if(alertView.tag == kALERTVIEW_REMOVE_ONE_INDEX){ if(buttonIndex==0){ //NO NSLog(@"[%s] BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex); //do nothing } else if(buttonIndex==1){ //YES NSLog(@"[%s] BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex); if(self.keyForSectionIndexToDelete != nil){ //Remove the section by key [self.indexPricesDictionary removeObjectForKey:self.keyForSectionIndexToDelete]; //sort the keys so sections appear alphabetically/numbericsearch (minus the one we just removed) [self updateTheSortedKeysArray]; //Delete the section from the table using animation [self.tableView beginUpdates]; [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:self.sectionIndexToDelete] withRowAnimation:UITableViewRowAnimationAutomatic]; [self.tableView endUpdates]; //required to trigger refresh of myTableCell.indexPathForCell else old values in UITableViewCells [self.tableView reloadData]; }else{ NSLog(@"ERROR: [%s] OBJECT is nil", __PRETTY_FUNCTION__); } } else { NSLog(@"ERROR: [%s] UNHANDLED BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex); } }else { NSLog(@"ERROR: [%s] unhandled ALERTVIEW TAG:%d", __PRETTY_FUNCTION__,alertView.tag); } }


Subclase el botón para almacenar el valor requerido, tal vez cree un protocolo (ControlWithData o algo así). Establezca el valor cuando agregue el botón a la celda de vista de tabla. En su evento de retoque, vea si el remitente obedece el protocolo y extraiga los datos. Normalmente almaceno una referencia al objeto real que se representa en la celda de vista de tabla.


Tenga en cuenta que aquí estoy usando una celda personalizada. Este código funciona perfectamente para mí.

@IBAction func call(sender: UIButton) { var contentView = sender.superview; var cell = contentView?.superview as EmployeeListCustomCell if (!(cell.isKindOfClass(EmployeeListCustomCell))) { cell = (contentView?.superview)?.superview as EmployeeListCustomCell } let phone = cell.lblDescriptionText.text! //let phone = detailObject!.mobile! let url:NSURL = NSURL(string:"tel://"+phone)!; UIApplication.sharedApplication().openURL(url); }


Una pequeña variación en la respuesta de Cocoanuts (que me ayudó a resolver esto) cuando el botón estaba en el pie de página de una tabla (lo que le impide encontrar la ''celda pulsada''):

-(IBAction) buttonAction:(id)sender; { id parent1 = [sender superview]; // UiTableViewCellContentView id parent2 = [parent1 superview]; // custom cell containing the content view id parent3 = [parent2 superview]; // UITableView containing the cell id parent4 = [parent3 superview]; // UIView containing the table UIView *myContentView = (UIView *)parent1; UITableViewCell *myTableCell = (UITableViewCell *)parent2; UITableView *myTable = (UITableView *)parent3; UIView *mainView = (UIView *)parent4; CGRect footerViewRect = myTableCell.frame; CGRect rect3 = [myTable convertRect:footerViewRect toView:mainView]; [cc doSomethingOnScreenAtY:rect3.origin.y]; }


Utilizo una solución que subclase UIButton y pensé que debería compartirla aquí, códigos en Swift:

class ButtonWithIndexPath : UIButton { var indexPath:IndexPath? }

Entonces recuerde actualizar su indexPath en cellForRow(at:)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let returnCell = tableView.dequeueReusableCell(withIdentifier: "cellWithButton", for: indexPath) as! cellWithButton ... returnCell.button.indexPath = IndexPath returnCell.button.addTarget(self, action:#selector(cellButtonPressed(_:)), for: .touchUpInside) return returnCell }

Así que cuando respondes al evento del botón puedes usarlo como

func cellButtonPressed(_ sender:UIButton) { if sender is ButtonWithIndexPath { let button = sender as! ButtonWithIndexPath print(button.indexPath) } }


Yo siempre uso etiquetas.

UITableviewCell subclasificar el UITableviewCell y manejar el botón presionando desde allí.


Yo usaría la propiedad de etiqueta como dijiste, estableciendo la etiqueta de esta manera:

[button setTag:indexPath.row];

luego obteniendo la etiqueta dentro de buttonPressedAction así:

((UIButton *)sender).tag

O

UIButton *button = (UIButton *)sender; button.tag;


cree una matriz nsmutable y coloque todos los botones en esa matriz usint [array addObject: yourButton];

en el boton presionando metodo

-

(void)buttonPressedAction:(id)sender { UIButton *button = (UIButton *)sender; for(int i=0;i<[yourArray count];i++){ if([buton isEqual:[yourArray objectAtIndex:i]]){ //here write wat u need to do } }


puede utilizar el patrón de etiqueta:

- (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:[indexPath row]]; //use the row as the current tag [cell.contentView addSubview:button]; [button release]; } UIButton *button = (UIButton *)[cell viewWithTag:[indexPath row]]; //use [indexPath row] [button setTitle:@"Edit" forState:UIControlStateNormal]; return cell; } - (void)buttonPressedAction:(id)sender { UIButton *button = (UIButton *)sender; //button.tag has the row number (you can convert it to indexPath) }


ACTUALIZACIÓN DE SWIFT 2

A continuación, le indicamos cómo averiguar qué botón se pulsó y enviar datos a otro ViewController desde el indexPath.row de ese botón. ¡ indexPath.row que ese es el punto para la mayoría!

@IBAction func yourButton(sender: AnyObject) { var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView) let indexPath = self.tableView.indexPathForRowAtPoint(position) let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as UITableViewCell print(indexPath?.row) print("Tap tap tap tap") }

Para aquellos que utilizan una clase ViewController y agregan un tableView, estoy usando un ViewController en lugar de un TableViewController, así que agregué manualmente el tableView para acceder a él.

Aquí está el código para pasar datos a otro VC cuando se toca ese botón y se pasa el indexPath.row la celda indexPath.row

@IBAction func moreInfo(sender: AnyObject) { let yourOtherVC = self.storyboard!.instantiateViewControllerWithIdentifier("yourOtherVC") as! YourOtherVCVIewController var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView) let indexPath = self.tableView.indexPathForRowAtPoint(position) let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as UITableViewCell print(indexPath?.row) print("Button tapped") yourOtherVC.yourVarName = [self.otherVCVariable[indexPath!.row]] self.presentViewController(yourNewVC, animated: true, completion: nil) }


// how do I know which button sent this message? // processing button press for this row requires an indexPath.

Bastante sencillo en realidad:

- (void)buttonPressedAction:(id)sender { UIButton *button = (UIButton *)sender; CGPoint rowButtonCenterInTableView = [[rowButton superview] convertPoint:rowButton.center toView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rowButtonCenterInTableView]; MyTableViewItem *rowItem = [self.itemsArray objectAtIndex:indexPath.row]; // Now you''re good to go.. do what the intention of the button is, but with // the context of the "row item" that the button belongs to [self performFooWithItem:rowItem]; }

Trabajando bien para mi: p

Si desea ajustar la configuración de la acción de destino, puede incluir el parámetro del evento en el método y luego usar los toques de ese evento para resolver las coordenadas del toque. Las coordenadas aún deben resolverse en los límites de la vista táctil, pero eso puede parecer más fácil para algunas personas.


A better way would be to subclass your button and add a indexPath property to it. //Implement a subclass for UIButton. @interface NewButton:UIButton @property(nonatomic, strong) NSIndexPath *indexPath; Make your button of type NewButton in the XIB or in the code whereever you are initializing them. Then in the cellForRowAtIndexPath put the following line of code. button.indexPath = indexPath; return cell; //As usual Now in your IBAction -(IBAction)buttonClicked:(id)sender{ NewButton *button = (NewButton *)sender; //Now access the indexPath by buttons property.. NSIndexPath *indexPath = button.indexPath; //:) }


func buttonAction(sender:UIButton!) { var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tablevw) let indexPath = self.tablevw.indexPathForRowAtPoint(position) let cell: TableViewCell = tablevw.cellForRowAtIndexPath(indexPath!) as TableViewCell println(indexPath?.row) println("Button tapped") }