Окрім відповіді Бреда Ларсона : для користувацьких шарів (які створені вами) ви можете використовувати делегування замість actionsсловника словника. Цей підхід є більш динамічним і може бути більш ефективним. І це дозволяє відключити всі неявні анімації без перерахування всіх анімаційних ключів.
На жаль, неможливо використовувати UIViews як власні делегати шару, оскільки кожен UIViewце вже делегат власного шару. Але ви можете використовувати простий клас помічників на кшталт цього:
@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
Використання (всередині подання):
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
Іноді зручно мати контролер виду в якості делегата для користувацьких підшарів перегляду; в цьому випадку немає необхідності в класі помічників, ви можете реалізувати actionForLayer:forKey:метод прямо всередині контролера.
Важлива примітка: не намагайтеся змінювати делегат UIViewбазового шару (наприклад, щоб включити неявну анімацію) - погані речі відбудуться :)
Примітка. Якщо ви хочете анімувати (не відключати анімацію для) шару, перемальовується, марно ставити [CALayer setNeedsDisplayInRect:]виклик всередині а CATransaction, оскільки фактичне перемальовування може (і, ймовірно, буде) траплятися іноді пізніше. Хороший підхід - використовувати власні властивості, як описано в цій відповіді .
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });