Respuestas:
En su didSelectRowAtIndexPath
necesita llamar deselectRowAtIndexPath
para anular la selección de la celda.
Entonces, sea lo que sea que esté haciendo didSelectRowAtIndexPath
, simplemente haga que llame deselectRowAtIndexPath
también.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Do some stuff when the row is selected
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-deselectRowAtIndexPath:animated:
método en su propiedad tableView desde -viewDidAppear
. Sin embargo, si tiene una vista de tabla en una subclase de UIViewController, debe llamar -deselectRowAtIndexPath:animated:
desde -viewDidAppear
usted mismo. :)
-viewWillAppear:
eso lo rompió. Agregar una llamada para [super viewWillAppear:animated]
que funcione nuevamente.
UITableViewController
's clearsSelectionOnViewWillAppear
propiedad se establece en YES
(que es el valor por defecto), y no se ha impedido [super viewWillAppear]
de ser llamado.
La forma más limpia de hacerlo es a la vista
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Unselect the selected row if any
NSIndexPath* selection = [self.tableView indexPathForSelectedRow];
if (selection) {
[self.tableView deselectRowAtIndexPath:selection animated:YES];
}
}
De esta manera, tiene la animación de desvanecer la selección cuando regrese al controlador, como debería ser.
Tomado de http://forums.macrumors.com/showthread.php?t=577677
Versión rápida
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// deselect the selected row if any
let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
if let selectedRowNotNill = selectedRow {
tableView.deselectRow(at: selectedRowNotNill, animated: true)
}
}
viewDidAppear
lugar.
indexPathForSelectedRow
llamada puede volver nula, por lo que debe verificarse. La documentación indica : Una ruta de índice que identifica los índices de fila y sección de la fila seleccionada, o nula si la ruta de índice no es válida.
¿Subclase -(void)viewWillAppear:(BOOL)animated
? El UITableViewCell seleccionado no deseleccionará cuando no llame [super viewWillAppear:animated];
a su método personalizado.
Para los usuarios de Swift, agregue esto a su código:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
Es la respuesta de paulthenerd, excepto en Swift en lugar de Obj-C.
Actualizado con Swift 4
Después de algunos experimentos, también basados en respuestas anteriores, tengo la conclusión de que el mejor comportamiento se puede lograr de 2 maneras: (casi idéntico en la práctica)
// First Solution: delegate of the table View
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
}
// Second Solution: With the life cycle of the view.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
if let selectedRow = selectedRow {
tableView.deselectRow(at: selectedRow, animated: false)
}
}
Personalmente, estoy adoptando la primera solución, porque es simplemente más conciso. Otra posibilidad, si necesita un poco de animación cuando regrese a su tableView, es usar viewWillAppear
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let selectedRow: IndexPath? = _view.tableView.indexPathForSelectedRow
if let selectedRow = selectedRow {
_view.tableView.deselectRow(at: selectedRow, animated: true)
}
}
Por último, pero no menos importante, si está utilizando un UITableViewController, también puede aprovechar la propiedad clearsSelectionOnViewWillAppear .
Para obtener el comportamiento que Kendall Helmstetter Gelner describe en su comentario, es probable que no desee deseleccionarRowAtIndexPath sino la propiedad clearSsectionOnViewWillAppear en su controlador. ¿Quizás esto se estableció en SÍ por accidente?
Vea el comentario en la plantilla predeterminada de Apple para las nuevas subclases UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
También recibí este problema para mi aplicación de desglose. Después de que un viewcontroller, que llamaré VC, regrese después de presionar otro ViewController, la celda seleccionada en VC permaneció resaltada. En mi aplicación, había creado VC para manejar el segundo nivel (de tres niveles) de mi desglose.
El problema en mi caso es que VC era un UIViewController (que contenía una Vista que contenía un TableView). En su lugar, hice de VC un UITableViewController (que contenía un TableView). La clase UITableViewController maneja automáticamente el resaltado de la celda de la tabla después de regresar de una inserción. La segunda respuesta a la publicación " Problema con deselectRowAtIndexPath en tableView " ofrece una respuesta más completa a este problema.
El problema no se produjo para el controlador de vista raíz porque cuando creé la aplicación como una "Aplicación basada en navegación" en XCode, el controlador de vista raíz resultante ya estaba hecho en la subclase UITableViewController.
Si ninguno de estos funciona para usted, considere esta solución alternativa:
Use una secuencia de desconexión para llamar:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
¿Por qué hacer esto? Principalmente si tiene problemas para ejecutar el código de deselección en el momento adecuado. Tuve problemas con que no funcionara en la vista Aparecerá así que el desenrollado funcionó mucho mejor.
Pasos:
Escriba la secuencia de desenrollado (o pegue desde arriba) en su primer VC (el que está en la tabla)
Ir a la segunda VC. Control-arrastre desde el botón Cancelar / Listo / Etc que está utilizando para descartar ese VC y arrastre hasta el ícono Salir en la parte superior.
Seleccione el desenrollar segue que creó en el paso 1
Buena suerte.
Estoy usando CoreData, por lo que el código que funcionó para mí fue una combinación de ideas de varias respuestas, en Swift:
override func viewDidAppear(_ animated: Bool) {
if let testSelected = yourTable.indexPathForSelectedRow {
yourTable.deselectRow(at: testSelected, animated: true)
}
super.viewDidAppear(true)
}
He tenido el mismo problema durante mucho tiempo, así que en caso de que alguien más esté luchando:
Eche un vistazo a su -tableView: cellForRowAtIndexPath:
y vea si está creando celdas o está utilizando un 'identificador de reutilización'. Si es esto último, asegúrese de que su tabla en IB tenga una celda con ese identificador. Si no está utilizando un identificador de reutilización, simplemente cree una nueva celda para cada fila.
Esto debería dar a su tabla la 'fila seleccionada desvanecida' esperada al aparecer.
Para Swift 3: preferiría que se use en viewDidDisappear
Definir:-
var selectedIndexPath = IndexPath()
En viewDidDisappear: -
override func viewDidDisappear(_ animated: Bool) {
yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}
En didSelectRowAtIndexPath: -
func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
selectedIndexPath = indexPath
}
si la celda permanece resaltada después de tocarla, puede llamar al método UITabelView,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
`[tableView deselectRowAtIndexPath:indexPath animated:YES];`
}
O bien, puede usar el siguiente método y modificarlo según sus requisitos,
// MARK: UITableViewDelegate
func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = UIColor.greenColor()
}
}
func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = UIColor.blackColor()
}
}
Xcode 10, Swift 4
Tuve este mismo problema y descubrí que dejé una llamada vacía para verWillAppear en la parte inferior de mi tableViewController. Una vez que eliminé la función de anulación vacía, la fila ya no permaneció resaltada al regresar a la vista tableView.
problema func
override func viewWillAppear(_ animated: Bool) {
// need to remove this function if not being used.
}
eliminar la función vacía resolvió mi problema.
deselectRowAtIndexPath
a mi viewDidAppear, si selecciono la fila aparece una nueva vista.