iphone - español - ¿Cómo obtener UITableViewCell indexPath de la Celda?
cocoa framework (11)
Swift 4.x
Para proporcionar acceso a mi celular, hice algo como esto:
Tengo una extensión de UIView:
extension UIView {
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}
Y luego ... en mi celda Clase:
class SomeCell: UITableViewCell {
func someMethod() {
if let myViewController = self.parentViewController as? CarteleraTableViewController {
let indexPath : IndexPath = (myViewController.tableView).indexPath(for: self)!
print(indexPath)
}
}
}
Eso es todo forma de mí.
Atentamente.
¿Cómo obtengo, desde una celda, su indexPath
en una UITableView
?
He buscado en el desbordamiento de pila y en google, pero toda la información está al revés. ¿Hay alguna forma de acceder al superView
/ UITableView
y luego buscar la celda?
Más información sobre el contexto: hay dos clases que tengo, una se llama Cue
y una se llama CueTableCell
(que es una subclase de UITableViewCell
) CueTableCell
es la representación visual de Cue
(ambas clases tienen punteros entre sí). Cue
objetos Cue
están en una lista vinculada y cuando el usuario ejecuta un determinado comando, la representación visual ( CueTableCell
) de la próxima Cue
debe ser seleccionada. Entonces, la clase Cue
llama al método de select
en la próxima entrada en la lista, que recupera la UITableView
de la cell
y llama a su selectRowAtIndexPath:animated:scrollPosition:
para lo cual necesita el indexPath
de UITableViewCell
.
Ponga una propiedad tableView débil en el archivo .h de la célula como:
@property (weak,nonatomic)UITableView *tableView;
Asigna la propiedad en el método cellForRowAtIndex como:
cell.tableView = tableView;
Ahora donde sea que necesite el indexPath de la celda:
NSIndexPath *indexPath = [cell.tableView indexPathForCell:cell];
En iOS 11.0, puede usar UITableView.indexPathForRow(at point: CGPoint) -> IndexPath?
:
if let indexPath = tableView.indexPathForRow(at: cell.center) {
tableView.selectRow
(at: indexPath, animated: true, scrollPosition: .middle)
}
Obtiene el punto central de la celda y luego tableView devuelve el indexPath correspondiente a ese punto.
La respuesta a esta pregunta realmente me ayudó mucho.
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
El sender
en mi caso era una UITableViewCell
y proviene del método prepareForSegue
.
Lo usé porque no tenía un TableViewController
pero tenía UITableView property outlet
Necesitaba encontrar el título de la Cell
y, por lo tanto, necesitaba saber el índice de la Píldora.
Espero que esto ayude a cualquiera!
Para dirigirse a aquellos que dicen "esta es una mala idea" , en mi caso, mi necesidad es que tengo un botón en mi UITableViewCell
que, cuando se presiona, es una transición a otra vista. Como esta no es una selección en la propia celda, [self.tableView indexPathForSelectedRow]
no funciona.
Esto me deja dos opciones:
- Almacene el objeto que necesito para pasar a la vista en la celda de la tabla. Si bien esto funcionaría, me
NSFetchedResultsController
hecho de tener unNSFetchedResultsController
porque no quiero almacenar todos los objetos en la memoria, especialmente si la tabla es larga. - Recupere el elemento del controlador de búsqueda utilizando la ruta de índice. Sí, parece feo que tengo que averiguar el
NSIndexPath
por un truco, pero en última instancia es menos costoso que almacenar objetos en la memoria.
indexPathForCell:
es el método correcto para usar, pero así es como lo haría (se supone que este código se implementa en una subclase de UITableViewCell
:
// uses the indexPathForCell to return the indexPath for itself
- (NSIndexPath *)getIndexPath {
return [[self getTableView] indexPathForCell:self];
}
// retrieve the table view from self
- (UITableView *)getTableView {
// get the superview of this class, note the camel-case V to differentiate
// from the class'' superview property.
UIView *superView = self.superview;
/*
check to see that *superView != nil* (if it is then we''ve walked up the
entire chain of views without finding a UITableView object) and whether
the superView is a UITableView.
*/
while (superView && ![superView isKindOfClass:[UITableView class]]) {
superView = superView.superview;
}
// if superView != nil, then it means we found the UITableView that contains
// the cell.
if (superView) {
// cast the object and return
return (UITableView *)superView;
}
// we did not find any UITableView
return nil;
}
PD: mi código real tiene acceso a todo esto desde la vista de tabla, pero estoy dando un ejemplo de por qué alguien podría querer hacer algo como esto directamente en la celda de la tabla.
Para veloz
let indexPath :NSIndexPath = (self.superview.superview as! UITableView).indexPathForCell(self)!
Pruebe con esto desde su UITableViewCell:
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
EDITAR: Parece que esto no funciona en iOS 8.1.2 y posteriores. Gracias a Chris Prince por señalarlo.
Pruebe con esto desde su UITableViewCell:
NSIndexPath *indexPath = [(UITableView *)self.superview.superview indexPathForCell:self];
Puedes probar este simple consejo:
en su clase UITableViewCell
:
@property NSInteger myCellIndex; //or add directly your indexPath
y en su método cellForRowAtIndexPath
:
...
[cell setMyCellIndex : indexPath.row]
ahora, puedes recuperar tu índice de celular en cualquier lugar
intente esto (solo funciona si el TableView tiene solo una sección y todas las celdas tienen alturas iguales):
//get current cell rectangle relative to its superview
CGRect r = [self convertRect:self.frame toView:self.superview];
//get cell index
int index = r.origin.y / r.size.height;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
Ayuda a leer la documentation , incluso si es considerada por algunos como controvertida (ver comentarios a continuación).
La célula no tiene ningún negocio sabiendo cuál es su ruta de índice. El controlador debe contener cualquier código que manipule los elementos de la interfaz de usuario en función del modelo de datos o que modifique los datos en función de las interacciones de la interfaz de usuario. (Ver MVC .)