Animate la vista de layout con respaldo usando UIKitDynamics

Quisiera utilizar un UISBehaviour de UIKitDynamics para darle vida a la animation (aspecto + cambio de position en la rotation) de un button que se coloca en una vista utilizando el layout automático.

Entiendo que al aplicar las fuerzas de UIKitDynamics necesito deshabilitar temporalmente las restricciones de layout automático del button. Estoy pensando en el siguiente process …

  1. Obtenga el centro de destino / límites del button antes de que ocurra la transición basada en el layout automático (pero después de que se dispare). Guardar ese valor.
  2. Deshabilitar temporalmente todas las configuraciones / restricciones automáticas del button
  3. Aplica el UISnapBehaviour. Aliméntelo con el centro de destino guardado o el valor de los límites del layout automático (desde el paso 1).
  4. Cuando finaliza la animation de UIKitDynamics, vuelva a habilitar las restricciones para prepararse para cualquier otro cambio de layout.

¿Es este el enfoque correcto?

¿Qué delegado / layout debe usarse para esos pasos respectivos + cómo puedo get el centro de destino de una vista desde el layout automático antes de que se produzca la animation / transición basada en el layout automático real?

Podría sugerirle un enfoque diferente que se aproxime al UISnapBehavior , pero evita intentar casarse con UIKit Dynamics con un layout automático en el que confía en el motor de layout automático para determinar la position final de la vista. (Obviamente, si supieras el destino final, solo suspenderías el layout automático, el complemento, y cuando se completara, entonces aplicarías las restricciones).

Para el efecto de rebote cuando la vista se ajusta a su lugar, puede usar animateWithDuration con el parámetro usar animateWithDuration , por ejemplo:

 // create the view UIView *view = ...; view.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:view]; // add all of the constraints for the final position NSDictionary *views = NSDictionaryOfVariableBindings(view); [self.view addConstraints:...]; // animate the application of those constraints with low `withSpringWithDamping` [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:0.0 options:0 animations:^{ [view layoutIfNeeded]; } completion:nil]; 

Si también quieres un poco de rotation a medida que encaja en su lugar, puedes usar animateKeyframesWithDuration :

 [UIView animateKeyframesWithDuration:1.0 delay:0.0 options:0 animations:^{ [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{ view.transform = CGAffineTransformMakeRotation(M_PI_4 / 2); }]; [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.25 animations:^{ view.transform = CGAffineTransformMakeRotation(-M_PI_4 / 4); }]; [UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.125 animations:^{ view.transform = CGAffineTransformMakeRotation(M_PI_4 / 16); }]; [UIView addKeyframeWithRelativeStartTime:0.875 relativeDuration:0.125 animations:^{ view.transform = CGAffineTransformMakeRotation(0); }]; } completion:nil]; 

Este no es precisamente el UISnapBehavior , pero lo aproxima bastante de cerca. Puede jugar con el time y la cantidad de rotaciones en la animation del cuadro de keys, así como también el factor de amortiguación del resorte. Pero esto ilustra un enfoque para get un comportamiento parecido a un complemento mediante la animation basada en bloques.