UIView animateWithDuration no anima la variación de cornerRadius

cornerRadius animar el cambio de la cornerRadius de una layer instancia de UIView , pero la variación de la cornerRadius tiene lugar inmediatamente.

Aquí está el código:

 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)]; view.layer.masksToBounds = YES; view.layer.cornerRadius = 10.0; [UIView animateWithDuration:1.0 animations:^{ [view.layer.cornerRadius = 0.0; }]; 

Gracias a todos los que me darán algunos consejos.

EDITAR:

Pude animar esta propiedad usando Core Animation , usando CABasicAnimation .

 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"]; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animation.fromValue = [NSNumber numberWithFloat:10.0f]; animation.toValue = [NSNumber numberWithFloat:0.0f]; animation.duration = 1.0; [viewToAnimate.layer addAnimation:animation forKey:@"cornerRadius"]; [animation.layer setCornerRadius:0.0]; 

tl; dr: El radio de la esquina no se puede animar en animateWithDuration:animations:


Qué dice la documentación sobre las animaciones de vista.

Como dice la sección sobre Animaciones en “Ver la guía de progtwigción para iOS”

Tanto UIKit como Core Animation brindan soporte para animaciones, pero el nivel de soporte proporcionado por cada tecnología varía. En UIKit, las animaciones se realizan usando objetos UIView

La lista completa de propiedades que puede animar usando cualquiera de las anteriores

 [UIView beginAnimations:context:]; [UIView setAnimationDuration:]; // Change properties here... [UIView commitAnimations]; 

o el más nuevo

 [UIView animateWithDuration:animations:]; 

(que estás usando) son:

  • marco
  • límites
  • centrar
  • transformar (CGAffineTransform, no el CATransform3D)
  • alfa
  • color de fondo
  • contentStretch

Como puede ver, cornerRadius no está en la lista.

Alguna confusión

Las animaciones de UIView solo están destinadas a animar propiedades de vista. Lo que confunde a las personas es que también pueden animar las mismas propiedades en la capa dentro del bloque de animación UIView, es decir, el marco, los límites, la posición, la opacidad, backgroundColor. Entonces, las personas ven las animaciones de capa dentro de animateWithDuration y creen que pueden animar cualquier propiedad de vista allí.

La misma sección continúa diciendo:

En los lugares donde desea realizar animaciones más sofisticadas o animaciones no compatibles con la clase UIView, puede utilizar Core Animation y la capa subyacente de la vista para crear la animación. Debido a que los objetos de vista y capa están estrechamente vinculados entre sí, los cambios en la capa de una vista afectan a la vista en sí.

Unas pocas líneas abajo puede leer la lista de propiedades animables de Core Animation donde ve este:

  • El borde de la capa (incluido si las esquinas de la capa están redondeadas)

Entonces, para animar la cornerRadius necesitas usar Core Animation como ya lo dijiste en tu pregunta actualizada (y respuesta). Acabo de agregar intenté explicar por qué es así.


Algunas aclaraciones adicionales

Cuando las personas leen la documentación que dice que animateWithDuration es la forma recomendada de animar, es fácil creer que está tratando de reemplazar CABasicAnimation, CAAnimationGroup, CAKeyframeAnimation, etc., pero realmente no es así. Está reemplazando el beginAnimations:context: y commitAnimations que viste arriba.

Uso esta extensión para animar el cambio del radio de la esquina:

 extension UIView { func addCornerRadiusAnimation(from: CGFloat, to: CGFloat, duration: CFTimeInterval) { let animation = CABasicAnimation(keyPath:"cornerRadius") animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) animation.fromValue = from animation.toValue = to animation.duration = duration layer.add(animation, forKey: "cornerRadius") layer.cornerRadius = to } } 

Se puede animar una variación de radio de esquina, pero la única forma de hacerlo es usar una CABasicAnimation. Espero que esto ayude a alguien por ahí.

Puede implementar la animación UIView como aquí: http://maniacdev.com/2013/02/ios-uiview-category-allowing-you-to-set-up-customizables-animation-properties

 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"]; animation.duration = DURATION; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animation.toValue = @(NEW_CORNER_RADIUS); animation.fillMode = kCAFillModeForwards; animation.removedOnCompletion = NO; [view.layer addAnimation:animation forKey:@"setCornerRadius:"]; 

No parece que esa sea una de las propiedades animables.

Vea aquí para la lista completa:

http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html

Puede hacer que esta propiedad sea animable en +[UIView animateWithDuration:] implementando -[actionForLayer:forKey] en su clase de vista. Vea esta pregunta para un ejemplo de cómo.

A partir de iOS 10 , puedes animar a cornerRadius:

 UIViewPropertyAnimator(duration: 3.0, curve: .easeIn) { square.layer.cornerRadius = 20 }.startAnimation()