Tengo un UITableView
con 5 UITableViewCells
. Cada celda contiene una 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 esta: en el buttonPressedAction:
método, ¿cómo sé 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 indexPath
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 resolví un poco haciendo lo siguiente. Todavía me gustaría tener una opinión si esta es la forma estándar de hacerlo o si hay una mejor 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];
[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 la celda podría quedar en espera. Se siente muy sucio. Debe haber una mejor manera.
ios
iphone
uitableview
uibutton
rienda
fuente
fuente
Respuestas:
En la muestra de accesorios de Apple se utiliza el siguiente método:
Luego, en el controlador táctil, la coordenada táctil recuperada y la ruta del índice se calcula a partir de esa coordenada:
fuente
Encontré 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
fuente
Así es como lo hago. Simple y conciso:
fuente
CGPointZero
lugar deCGPointMake(0, 0)
;-)Encontré una buena solución a este problema en otro lugar, sin perder el tiempo con las etiquetas en el botón:
fuente
buttonPressedAction:
perobuttonPressedAction:forEvent:
.¿Qué tal enviar la información como
NSIndexPath
en elUIButton
uso de inyección en tiempo de ejecución?1) Necesita tiempo de ejecución en la importación
2) agregar constante estática
3) agregue
NSIndexPath
a su botón en tiempo de ejecución usando:(nulo) setMetaData: (id) objetivo conObject: (id) newObj
4) al presionar el botón obtener metadatos usando:
(id) metaData: (id) objetivo
Disfrutar
fuente
La respuesta de (@Vladimir) es Swift:
Aunque la comprobación
indexPath != nil
me da el dedo ... "NSIndexPath no es un subtipo de NSString"fuente
Con Swift 4.2 y iOS 12, puede elegir uno de los 5 ejemplos completos siguientes para resolver su problema.
# 1 El uso de
UIView
'sconvert(_:to:)
yUITableView
' sindexPathForRow(at:)
# 2 El uso de
UIView
'sconvert(_:to:)
yUITableView
' sindexPathForRow(at:)
(alternativa)Esta es una alternativa al ejemplo anterior donde pasamos
nil
altarget
parámetro enaddTarget(_:action:for:)
. De esta manera, si el primer respondedor no implementa la acción, se enviará al siguiente respondedor en la cadena del respondedor hasta que se encuentre una implementación adecuada.# 3 Usando
UITableView
'sindexPath(for:)
y patrón de delegadoEn este ejemplo, configuramos el controlador de vista como el delegado de la celda. Cuando se toca el botón de la celda, se activa una llamada al método apropiado del delegado.
# 4. Uso de
UITableView
'syindexPath(for:)
un cierre para delegaciónEsta es una alternativa al ejemplo anterior donde usamos un cierre en lugar de una declaración de delegado de protocolo para manejar el toque del botón.
# 5. El uso de
UITableViewCell
'saccessoryType
yUITableViewDelegate
' stableView(_:accessoryButtonTappedForRowWith:)
Si su botón es un
UITableViewCell
control accesorio estándar, cualquier toque en él activará una llamada aUITableViewDelegate
"s"tableView(_:accessoryButtonTappedForRowWith:)
, lo que le permitirá obtener la ruta de índice relacionada.fuente
fuente
Usaría la propiedad de etiqueta como dijiste, configurando la etiqueta de esta manera:
luego obtener la etiqueta dentro del botónPressedAction así:
O
fuente
tag
es un entero Parece un poco torpe codificar / decodificar rutas de índice en etiquetas de vista.Aunque me gusta la forma de la etiqueta ... si no desea usar etiquetas por cualquier razón, puede crear un miembro
NSArray
de botones prefabricados:luego cree esos botones antes de representar el TableView y empújelos en la matriz.
Luego dentro de la
tableView:cellForRowAtIndexPath:
función puedes hacer:Luego en la
buttonPressedAction:
función, puedes hacerfuente
PARA MANEJAR SECCIONES: almacené NSIndexPath en un UITableViewCell personalizado
IN CLKIndexPricesHEADERTableViewCell.xib
IN IB Agregue UIButton a XIB - ¡NO agregue acción!
Agregar salida @property (retención, no atómica) IBOutlet UIButton * buttonIndexSectionClose;
NO CTRL + ARRASTRE una acción en IB (hecho en el código a continuación)
En viewForHeaderInSection (también debería funcionar para cellForRow ... etc si su tabla tiene solo 1 sección)
... use la sección para obtener datos para su celda
...rellenarlo
El USUARIO presiona el botón ELIMINAR en un encabezado de sección y esto llama
En este ejemplo, agregué un botón Eliminar, por lo que debería mostrar UIAlertView para confirmarlo
Guardo la sección y la clave en el diccionario almacenando información sobre la sección en un ivar en el VC
fuente
fuente
A mí también me funciona, gracias @Cocoanut
Encontré 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
fuente
puedes usar el patrón de etiqueta:
fuente
¿Me estoy perdiendo de algo? ¿No puedes usar el remitente para identificar el botón? El remitente te dará información como esta:
Luego, si desea cambiar las propiedades del botón, diga la imagen de fondo que acaba de decirle al remitente:
Si necesita la etiqueta, entonces el método de ACBurk está bien.
fuente
Bastante sencillo en realidad:
Trabajando bien para mí: P
si desea ajustar su configuración de acción de destino, puede incluir el parámetro de 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.
fuente
cree una matriz nsmutable y coloque todos los botones en esa matriz usint [array addObject: yourButton];
en el método de presionar el botón
-
fuente
Una ligera 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 en la que se hizo clic':
fuente
Siempre uso etiquetas.
Debe subclasificar
UITableviewCell
y manejar el botón presionar desde allí.fuente
Es sencillo; crea una celda personalizada y toma una salida de botón
cambiar la identificación en el método anterior a
(UIButton *)
Puede obtener el valor de qué botón está siendo tocado haciendo sender.tag.
fuente
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 la vista de tabla.
fuente
ACTUALIZACIÓN DE SWIFT 2
¡Aquí se explica cómo averiguar qué botón se tocó + enviar datos a otro ViewController desde ese botón,
indexPath.row
ya que supongo que ese es el punto para la mayoría!Para aquellos que usan una clase ViewController y agregaron 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 al tocar ese botón y pasar la celda
indexPath.row
fuente
Tenga en cuenta que estoy usando una celda personalizada, este código funciona perfectamente para mí
fuente
La solución de Chris Schwerdt pero luego en Swift funcionó para mí:
fuente
Este problema tiene dos partes:
1) Obtener la ruta del índice
UITableViewCell
que contiene presionadoUIButton
Hay algunas sugerencias como:
Actualizando
UIButton
'stag
encellForRowAtIndexPath:
el método de uso de ruta del índicerow
de valor. Esta no es una buena solución, ya que requiere una actualizacióntag
continua y no funciona con vistas de tabla con más de una sección.Adición de una
NSIndexPath
propiedad de celda personalizado y su actualización en lugar deUIButton
'stag
en elcellForRowAtIndexPath:
método. Esto resuelve el problema de múltiples secciones, pero aún no es bueno, ya que requiere una actualización siempre.Mantener una referencia débil al elemento primario
UITableView
en la celda personalizada mientras se crea y se usa elindexPathForCell:
método para obtener la ruta del índice. Parece un poco mejor, no es necesario actualizar nada en elcellForRowAtIndexPath:
método, pero aún requiere establecer una referencia débil cuando se crea la celda personalizada.Usar la
superView
propiedad de la celda para obtener una referencia a padreUITableView
. No es necesario agregar ninguna propiedad a la celda personalizada, y no es necesario establecer / actualizar nada en la creación / posterior. Pero la célulasuperView
depende de los detalles de implementación de iOS. Por lo tanto, no se puede usar directamente.Pero esto se puede lograr usando un bucle simple, ya que estamos seguros de que la celda en cuestión debe estar en un UITableView:
Por lo tanto, estas sugerencias se pueden combinar en un método de celda personalizado simple y seguro para obtener la ruta del índice:
De ahora en adelante, este método puede usarse para detectar cuál
UIButton
se presiona.2) Informar a otras partes sobre el evento de presionar un botón
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 maneje elUITableView
). Por lo tanto, este evento de clic de botón se puede manejar en un nivel de abstracción y lógica similar aldidSelectRowAtIndexPath:
método del delegado UITableView.Se pueden usar dos enfoques para esto:
a) Delegación: la celda personalizada puede tener una
delegate
propiedad y puede definir un protocolo. Cuando se presiona el botón, simplemente realiza sus métodos de delegado en sudelegate
propiedad. Pero estadelegate
propiedad debe establecerse para cada celda personalizada cuando se crean. Como alternativa, la celda personalizada puede elegir realizar sus métodos de delegado en la vista de la tabla principaldelegate
también.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
userInfo
objeto. No es necesario configurar nada para cada celda, basta con agregar un observador para la notificación de la celda personalizada.fuente
Utilizo una solución de esa subclase
UIButton
y pensé que debería compartirla aquí, códigos en Swift:Luego recuerde actualizar su indexPath en
cellForRow(at:)
Entonces, al responder al evento del botón, puede usarlo como
fuente