Brad Larson'un cevabına ek olarak : (sizin tarafınızdan oluşturulan) özel katmanlar için , katmanın sözlüğünü değiştirmek yerine temsilci kullanabilirsinizactions
. Bu yaklaşım daha dinamik ve daha performanslı olabilir. Ayrıca, tüm animasyonlu anahtarları listelemek zorunda kalmadan tüm örtülü animasyonların devre dışı bırakılmasına izin verir.
Ne yazık ki, UIView
s'yi özel katman delegeleri olarak kullanmak imkansızdır , çünkü her UIView
biri zaten kendi katmanının bir temsilcisidir. Ancak bunun gibi basit bir yardımcı sınıf kullanabilirsiniz:
@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
Kullanım (görünümün içinde):
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
Bazen görünümün denetleyicisini, görünümün özel alt katmanları için temsilci olarak kullanmak uygun olur; bu durumda bir yardımcı sınıfa gerek yoktur, actionForLayer:forKey:
yöntemi doğrudan kontrolörün içine uygulayabilirsiniz .
Önemli not: UIView
temel katman temsilcisini değiştirmeye çalışmayın (ör. Örtülü animasyonları etkinleştirmek için) - kötü şeyler olur :)
Not: katman yeniden çizimlerini canlandırmak (animasyonu devre dışı bırakmak istemiyorsanız), a'nın içine [CALayer setNeedsDisplayInRect:]
çağrı koymak işe yaramaz CATransaction
, çünkü gerçek yeniden çizme bazen daha sonra gerçekleşebilir (ve muhtemelen gerçekleşecektir). İyi yaklaşım, bu cevapta açıklandığı gibi özel özellikler kullanmaktır .
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });