Además de la respuesta de Brad Larson : para capas personalizadas (creadas por usted) puede usar la delegación lugar de modificar el actionsdiccionario de la capa . Este enfoque es más dinámico y puede ser más eficaz. Y permite deshabilitar todas las animaciones implícitas sin tener que enumerar todas las teclas animables.
Desafortunadamente, es imposible usar UIViews como delegados de capa personalizados, porque cada uno UIViewya es un delegado de su propia capa. Pero puede usar una clase auxiliar simple como esta:
@interface MyLayerDelegate : NSObject
@property (nonatomic, assign) BOOL disableImplicitAnimations;
@end
@implementation MyLayerDelegate
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event
{
if (self.disableImplicitAnimations)
return (id)[NSNull null]; // disable all implicit animations
else return nil; // allow implicit animations
// you can also test specific key names; for example, to disable bounds animation:
// if ([event isEqualToString:@"bounds"]) return (id)[NSNull null];
}
@end
Uso (dentro de la vista):
MyLayerDelegate *delegate = [[MyLayerDelegate alloc] init];
// assign to a strong property, because CALayer's "delegate" property is weak
self.myLayerDelegate = delegate;
self.myLayer = [CALayer layer];
self.myLayer.delegate = delegate;
// ...
self.myLayerDelegate.disableImplicitAnimations = YES;
self.myLayer.position = (CGPoint){.x = 10, .y = 42}; // will not animate
// ...
self.myLayerDelegate.disableImplicitAnimations = NO;
self.myLayer.position = (CGPoint){.x = 0, .y = 0}; // will animate
A veces es conveniente tener el controlador de vista como delegado para las subcapas personalizadas de vista; en este caso no hay necesidad de una clase auxiliar, puede implementar el actionForLayer:forKey:método directamente dentro del controlador.
Nota importante: no intente modificar el delegado de UIViewla capa subyacente (por ejemplo, para habilitar animaciones implícitas), sucederán cosas malas :)
Nota: si desea animar (no deshabilitar la animación para) los redibujos de capa, es inútil poner la [CALayer setNeedsDisplayInRect:]llamada dentro de un CATransaction, porque el redibujo real puede (y probablemente) ocurrirá a veces más tarde. El buen enfoque es usar propiedades personalizadas, como se describe en esta respuesta .
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });