iphone - uitableviewcell - UITableView ancla filas a la parte inferior
uitableviewcontroller (8)
Bueno, si cargas tu tabla con NSMutableArray, te sugiero que clasifiques la matriz en el orden inverso. Entonces, la vista de tabla se completará como lo desee.
Tengo un UITableView que necesita introducir nuevo contenido desde abajo. Así es como se comporta una vista de tabla cuando la vista está llena y agrega nuevas filas con animación.
Lo comencé alterando el contentInset a medida que se introducen las filas, pero cuando cambian las cosas se apagan y la animación de la entrada es incorrecta ... Mi problema con este enfoque se ve agravado por el hecho de que los usuarios pueden eliminar filas, y la fila actualización de contenido, haciendo que cambien de tamaño (cada fila tiene su propia altura, que cambia).
¿Alguna recomendación sobre cómo hacer que las filas de UITableView aparezcan siempre en la parte inferior del espacio de visualización de UITableView?
Cree un encabezado de tabla que sea el alto de la pantalla (en cualquier orientación en la que se encuentre) MENOS la altura de las filas que desea que sean visibles. Si no hay filas, entonces el encabezado es el alto completo de la vista de tabla. A medida que se agregan filas, reduzca simultáneamente la altura del encabezado de la tabla por la altura de la nueva fila. Esto significa cambiar la altura del marco de la vista que proporciona para el encabezado de la tabla. El punto es llenar el espacio sobre las filas de la tabla para dar la apariencia de que las filas están ingresando desde la parte inferior. El uso de un encabezado de tabla (o encabezado de sección) empuja hacia abajo los datos de la tabla. Puede poner lo que quiera en la vista de encabezado, incluso tenerlo en blanco y transparente si lo desea.
Esto debería tener el efecto que estás buscando, creo.
Mira el atributo tableHeaderView
. Simplemente configura esto para la vista que quieres que se muestre en el encabezado de la tabla. Luego puede manipularlo según sea necesario a medida que agrega filas. No puedo recordar lo enérgico que debe ser para obtener la vista para actualizar realmente en la interfaz de usuario. Podría ser tan simple como llamar a setNeedsDisplay
, en todo caso.
Alternativamente, mire los métodos tableView:viewForHeaderInSection:
y tableView:heightForHeaderInSection:
Similar a usar una vista de encabezado de tabla, le gustaría tener una variable de instancia que haya configurado una vez, pero que puede acceder desde estos métodos para devolver la vista o su altura, respectivamente. Cuando necesite cambiar la vista de la (primera) sección, puede usar reloadSections:withAnimation:
para forzar una actualización de la vista en la pantalla después de haber cambiado la altura de las vistas (o el contenido).
¿Algo de eso tiene sentido? Eso espero. :-)
El método aceptado introduce problemas para mi aplicación: la barra de desplazamiento está en el lado equivocado y deshace los separadores de celdas para UITableViewStyleGrouped
Para solucionar este problema, usa lo siguiente
tableView.transform = CGAffineTransformMakeScale (1,-1);
y
cell.contentView.transform = CGAffineTransformMakeScale (1,-1);
// if you have an accessory view
cell.accessoryView.transform = CGAffineTransformMakeScale (1,-1);
Solo quería agregar algo a todas estas respuestas con respecto al uso de esta técnica con UICollectionView ... A veces, al invalidar el diseño, mis células se transformaban de forma incorrecta, encontré que en las subclases UICollectionViewCell y UICollectionReusableView tenía que hacer esto:
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
[super applyLayoutAttributes:layoutAttributes];
[self setTransform:CGAffineTransformMakeScale(1, -1)];
}
Swift 3.01 - Otra solución puede ser, girar y voltear la vista de tabla. Funciona muy bien para mí y no meterse con la animación y es menos trabajo para los datos de recarga en la vista de tabla.
self.tableView.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(Double.pi)))
self.tableView.transform = CGAffineTransform.init(translationX: -view.frame.width, y: view.frame.height)
Tengo una solución que me funciona a la perfección, pero causa un montón de doble pensamiento, así que no es tan simple en teoría como lo es en la práctica ... un poco ...
Paso 1, aplique una transformación a la vista de tabla girándola 180deg
tableView.transform = CGAffineTransformMakeRotation(-M_PI);
Paso 2, gire su celda en bruto 180deg en tableView: cellForRowAtIndexPath:
cell.transform = CGAffineTransformMakeRotation(M_PI);
Paso 3, invierta su origen de datos. Si está utilizando un NSMutableArray inserte objetos nuevos en la ubicación 0 en lugar de usar AddObject ...
Ahora, la parte difícil es recordar que la izquierda es correcta y la derecha se deja solo en el nivel de la mesa, así que si usa
[tableView insertRowsAtIndexPaths:targetPath withRowAnimation:UITableViewRowAnimationLeft]
ahora tiene que ser
[tableView insertRowsAtIndexPaths:targetPath withRowAnimation:UITableViewRowAnimationRight]
y lo mismo para eliminaciones, etc.
Dependiendo de cuál sea su almacén de datos, es posible que deba manejarlo en orden inverso también ...
Nota: gire las celdas OPUESTA a la tabla, de lo contrario, la inexactitud del punto flotante podría hacer que la transformación se salga perfecta y obtendrá bugs en algunos gráficos de vez en cuando mientras se desplaza ... menor pero molesto.
Un enfoque similar al ima747, pero girando 180 grados también hace que el indicador de desplazamiento vaya al lado opuesto. En cambio, volteé la vista de tabla y sus celdas verticalmente.
self.tableView.transform = CGAffineTransformMakeScale(1, -1); //in viewDidLoad
cell.transform = CGAffineTransformMakeScale(1, -1);//in tableView:cellForRowAtIndexPath:
dataSourceArray = dataSourceArray.reversed()
tableView.transform = CGAffineTransform(scaleX: 1, y: -1)
cell.transform = CGAffineTransform(scaleX: 1, y: -1)
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let text = textField.text {
dataSourceArray.insert(text, at: 0)
self.tableView.reloadData()
textField.text = ""
}
textField.resignFirstResponder()
return true
}