¿Se pueden animar los NSLayoutConstraints? [duplicar]

Resuelto borrrden asked hace 54 años • 4 respuestas

Estoy intentando animar algunas vistas para que queden bloqueadas por el teclado gigante en posición horizontal. Funciona bien si simplemente animo los fotogramas, pero otros han sugerido que esto es contraproducente y que debería actualizar NSLayoutConstraints. Sin embargo, no parecen ser animables. ¿Alguien ha conseguido que funcionen con éxito?

//heightFromTop is an NSLayoutConstraint referenced from IB
[UIView animateWithDuration:0.25 animations:^{
    self.heightFromTop.constant= 550.f;
}];

El resultado es un salto instantáneo a la altura en cuestión.

borrrden avatar Jan 01 '70 08:01 borrrden
Aceptado

Simplemente sigue este patrón exacto:

self.heightFromTop.constant = 550.0f;
[myView setNeedsUpdateConstraints];

[UIView animateWithDuration:0.25f animations:^{
   [myView layoutIfNeeded];
}];

¿Dónde myViewestá la vista donde self.heightFromTopse agregó? Su vista está "saltando" porque lo único que hizo en el bloque de animación fue establecer la restricción, lo que no genera diseños de inmediato. En su código, el diseño ocurre en el siguiente ciclo de ejecución después de configurar heightFromTop.constant, y en ese momento ya está fuera del alcance del bloque de animación.

En Swift 2:

self.heightFromTop.constant = 550
myView.setNeedsUpdateConstraints()

UIView.animateWithDuration(0.25, animations: {
   myView.layoutIfNeeded()
})
John Estropia avatar Oct 17 '2012 03:10 John Estropia

La forma sugerida por Apple es un poco diferente ( consulte el ejemplo en la sección "Animación de cambios realizados mediante diseño automático" ). Primero debes llamar a layoutIfNeeded antes de la animación. Luego agregue sus elementos de animación dentro del bloque de animación y luego llame a layoutIfNeeded al final nuevamente. Para los chicos como yo que estamos haciendo la transición al diseño automático, es más similar a las animaciones anteriores que estábamos haciendo con los fotogramas dentro de los bloques de animación. Solo necesitamos llamar a layoutIfNeeded dos veces: antes y después de las animaciones:

[self.view layoutIfNeeded]; // Ensures that all pending layout operations have been completed

[UIView animateWithDuration:1.0f animations:^{

  // Make all constraint changes here
  self.heightFromTop.constant= 550.f;

  [self.view layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes

}];
Centurion avatar Jan 23 '2014 11:01 Centurion

Probé el enfoque de @Centurion, pero de alguna manera mi vista se animaba en un fotograma incorrecto si se cargaba desde el guión gráfico. El problema desaparece si reemplazo el primero layoutIfNeededpor updateConstraintsIfNeeded, aunque no tengo idea de por qué. Si alguien puede dar una explicación se lo agradecería mucho.

[self.view updateConstraintsIfNeeded];
[UIView animateWithDuration:1.0 animations:^{
    self.myConstraint.constant= 100;
    [self.view layoutIfNeeded];
}];
Joseph Lin avatar Jan 24 '2014 00:01 Joseph Lin