Además de la respuesta de Brad Larson : para capas personalizadas (creadas por usted) puede usar la delegación lugar de modificar el actions
diccionario 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 UIView
s como delegados de capa personalizados, porque cada uno UIView
ya 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 UIView
la 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(), ^{ });