En plus de la réponse de Brad Larson : pour les couches personnalisées (que vous avez créées), vous pouvez utiliser la délégation au lieu de modifier le actionsdictionnaire des couches . Cette approche est plus dynamique et peut être plus performante. Et il permet de désactiver toutes les animations implicites sans avoir à lister toutes les clés animables.
Malheureusement, il est impossible d'utiliser les UIViews comme délégués de couche personnalisés, car chacun UIViewest déjà un délégué de sa propre couche. Mais vous pouvez utiliser une classe d'assistance simple comme celle-ci:
@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
Utilisation (à l'intérieur de la vue):
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
Parfois, il est pratique d'avoir le contrôleur de vue comme délégué pour les sous-couches personnalisées de vue; dans ce cas, il n'y a pas besoin d'une classe d'assistance, vous pouvez implémenter la actionForLayer:forKey:méthode directement dans le contrôleur.
Note importante: n'essayez pas de modifier le délégué de UIViewla couche sous-jacente (par exemple pour activer des animations implicites) - de mauvaises choses vont arriver :)
Remarque: si vous souhaitez animer (et non désactiver l'animation pour) les redessins de calques, il est inutile de mettre un [CALayer setNeedsDisplayInRect:]appel à l'intérieur de a CATransaction, car un redessinage réel peut (et se produira probablement) parfois plus tard. La bonne approche consiste à utiliser des propriétés personnalisées, comme décrit dans cette réponse .
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });