Selain jawaban Brad Larson : untuk lapisan khusus (yang dibuat oleh Anda), Anda dapat menggunakan delegasi alih-alih memodifikasi actions
kamus layer . Pendekatan ini lebih dinamis dan mungkin lebih berkinerja. Dan itu memungkinkan penonaktifan semua animasi implisit tanpa harus mendaftar semua kunci yang dapat dianimasikan.
Sayangnya, tidak mungkin untuk menggunakan UIView
s sebagai delegasi lapisan kustom, karena masing UIView
- masing sudah merupakan delegasi dari lapisannya sendiri. Tetapi Anda dapat menggunakan kelas pembantu sederhana seperti ini:
@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
Penggunaan (di dalam tampilan):
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
Terkadang, nyaman untuk memiliki pengontrol tampilan sebagai delegasi untuk sublayer khusus tampilan; dalam hal ini tidak perlu kelas pembantu, Anda dapat menerapkan actionForLayer:forKey:
metode tepat di dalam controller.
Catatan penting: jangan mencoba memodifikasi delegasi dari UIView
lapisan yang mendasarinya (mis. Untuk mengaktifkan animasi tersirat) - hal-hal buruk akan terjadi :)
Catatan: jika Anda ingin menghidupkan kembali (tidak menonaktifkan animasi untuk) layer redraw, tidak ada gunanya memasukkan [CALayer setNeedsDisplayInRect:]
panggilan ke dalam CATransaction
, karena redrawing yang sebenarnya mungkin (dan mungkin akan) terjadi kadang-kadang nanti. Pendekatan yang baik adalah dengan menggunakan properti khusus, seperti yang dijelaskan dalam jawaban ini .
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });