ios - ¿Cómo animar la altura de UITableViewCell utilizando el diseño automático?
objective-c ios8 (2)
Lo siguiente me funcionó:
Preparación:
En
viewDidLoad
a la vista de tabla que use celdas de tamaño automático:tableView.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = 44; // Some average height of your cells
Agregue las restricciones como lo haría normalmente, ¡pero agréguelas a
contentView
lacontentView
!
Animar cambios de altura:
Digamos que cambias la constant
una restricción:
myConstraint.constant = newValue;
... o usted agrega / elimina restricciones.
Para animar este cambio, proceda de la siguiente manera:
Dile a contentView para animar el cambio:
[UIView animateWithDuration: 0.3 animations: ^{ [cell.contentView layoutIfNeeded] }]; // Or self.contentView if you''re doing this from your own cell subclass
Luego diga a la vista de tabla que reaccione al cambio de altura con una animación
[tableView beginUpdates]; [tableView endUpdates];
La duración de 0,3 en el primer paso es lo que parece ser la duración que utiliza UITableView para sus animaciones al llamar a begin / endUpdates.
Bono: cambie la altura sin animación y sin volver a cargar toda la tabla:
Si desea hacer lo mismo que arriba, pero sin una animación, haga esto en su lugar:
[cell.contentView layoutIfNeeded];
[UIView setAnimationsEnabled: FALSE];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled: TRUE];
Resumen:
// Height changing code here:
// ...
if (animate) {
[UIView animateWithDuration: 0.3 animations: ^{ [cell.contentView layoutIfNeeded]; }];
[tableView beginUpdates];
[tableView endUpdates];
}
else {
[cell.contentView layoutIfNeeded];
[UIView setAnimationsEnabled: FALSE];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled: TRUE];
}
Puede ver mi implementación de una celda que se expande cuando el usuario la selecciona here (Swift puro y autolayout puro - verdaderamente el camino del futuro).
Hay muchas preguntas similares en Stack Overflow sobre la animación de altura UITableViewCell
, pero nada funciona para la nueva vista de tabla basada en el diseño automático de iOS8. Mi problema:
Celda personalizada:
@property (weak, nonatomic) IBOutlet iCarousel *carouselView;
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
@property (weak, nonatomic) IBOutlet UIButton *seeAllButton;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *carouselHeightConstraint;
Tenga en cuenta el carouselHeightConstraint
. Esta es una restricción de altura para la subvista de vista de contenido (la única subvista).
La altura se establece en 230.0f
por ejemplo. En la primera carga parece:
Luego, en la acción Ver todos quiero expandir la celda, mi código:
- (IBAction)seeAllButtonAction:(id)sender {
BOOL vertical = !self.carouselCell.carouselView.vertical;
self.carouselCell.carouselView.type = vertical ? iCarouselTypeCylinder : iCarouselTypeLinear;
self.carouselCell.carouselView.vertical = vertical;
[UIView transitionWithView:self.carouselCell.carouselView
duration:0.2
options:0
animations:^{
self.carouselCell.carouselHeightConstraint.constant = vertical ? CGRectGetHeight(self.tableView.frame) : 230;
[self.carouselCell setNeedsUpdateConstraints];
[self.carouselCell updateConstraintsIfNeeded];
[self.tableView beginUpdates];
[self.tableView endUpdates];
completion:^(BOOL finished) {
}];
}
Como puedes ver, trato de usar esta buena solución antigua:
¿Puede animar un cambio de altura en un UITableViewCell cuando se selecciona?
Y el resultado:
Mi celular se encoge a 44.0f
altura.
Pregunta:
¿Por qué sucede esto? Espero ver mi celular sin problemas expandiéndose con la magia del auto-layot.
Nota:
No quiero usar -tableView:heightForRowAtIndexPath:
Es la era de diseño automático, ¿verdad?
Me gustaría agregar algunos puntos a la respuesta de Alex.
Si llama a beginUpdates y endUpdates dentro de cellForRowAtIndexPath o willDisplayCell, su aplicación se bloqueará. Después de animar el aumento de su celda, es posible que desee que permanezca igual después de desplazarse a su tableView. También es posible que desee que el resto de las celdas mantengan su altura igual. Pero recuerde que las celdas son reutilizables, por lo que podría terminar con otras celdas que tengan una altura mayor.
Como resultado, tendrá que establecer la constante de restricción dentro de cellForRowAtIndexPath dependiendo del elemento que representa. Pero si llama a layoutIfNeded después, mostrará una advertencia con sus restricciones. Mi creencia es que intenta generar el diseño de la celda antes de que se calcule su nueva altura.
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
...
myConstraint.constant = itemForCell.value == "x" ? 50 : 20 // stop right here
cell.layoutIfNeeded() <- don''t do this or some of your constraints will break
beginUpdates() <-- if you do this your app will crash
endUpdates() <-- same here