Selain jawaban Brad Larson : untuk lapisan khusus (yang dibuat oleh Anda), Anda dapat menggunakan delegasi alih-alih memodifikasi actionskamus 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 UIViews 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 UIViewlapisan 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(), ^{ });