CATransaction
What the flush ?!
Amadour Griffais
CocoaHeads Paris
9 janvier 2014
Core Animation
• crée et manipule des objets graphiques
• les affiche
• les anime
Core Animation
Core Animation
Core Animation
Core Animation
Core Animation
Model
Ab

CALayer
CAAnimation
Core Animation
Model
Ab

Render server

CALayer
CAAnimation

C++
Core Animation
Model
Ab

Render server

CALayer
CAAnimation

C++
Core Animation
Model
Ab

CALayer
CAAnimation
Core Animation
Model
Ab

CALayer
CAAnimation
CATransaction
Core Animation Programming Guide
Explicit Transactions Let You Change Animation Parameters
[CATransaction
[CATransaction
layer.position
[CATransaction

begin];
setAnimationDuration:0.5];
= CGPoint(100,100);
commit];
CATransaction
Model
Ab
CATransaction
Model
0.5s

Ab
CATransaction
Core Animation Programming Guide
Explicit Transactions Let You Change Animation Parameters
[CATransaction
[CATransaction
layer.position
[CATransaction

begin];
setAnimationDuration:0.5];
= CGPoint(100,100);
commit];

Disable Actions Temporarily Using the CATransaction Class
[CATransaction
[CATransaction
layer.position
[CATransaction

begin];
setDisableActions:YES];
= CGPoint(100,100);
commit];
CATransaction
Model
Ab
CATransaction
Model
Ab
CATransaction Class Reference
CATransaction Class Reference
Model

Render server
Model
Ab

Render server
[CATransaction flush];
Model
Ab

Render server
[CATransaction flush];
Model
Ab

Render server
Ab
[CATransaction flush];
• Commit de la transaction implicite
• Englobe toutes les transaction explicites
• Envoie les modifications au render server
[CATransaction flush];
• A chaque tour de runloop
• Provoque layout si nécessaire
[CATransaction flush];
• A chaque tour de runloop
• Provoque layout si nécessaire
• Provoque display si nécessaire
[CATransaction flush];
• Equivalent à [CATransaction commit];
• Attend la fin des transaction explicites
• Définit le beginTime des animations !
[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
CAAnimation* anim = [CABasicAnimation animationWithKeyPath:@"opacity"];
[layer addAnimation:anim forKey:@"opacity"];
//<CABasicAnimation:0xc028980; duration = 0.5; keyPath = opacity>
[CATransaction commit];
//<CABasicAnimation:0xc028980; duration = 0.5; keyPath = opacity>
[CATransaction flush];
//<CABasicAnimation:0xc028980; beginTimeMode = absolute;
//
beginTime = 11797.4; duration = 0.5; keyPath = opacity>
En pratique
Déclencher une animation d’attente avant de
bloquer le main thread
[activityIndicator startAnimating];
[self doReallyLongStuff];
En pratique
Déclencher une animation d’attente avant de
bloquer le main thread
[activityIndicator startAnimating];
[CATransaction flush];
[self doReallyLongStuff];
En pratique
Appliquer des animations implicites à des
layers qui viennent d’être ajoutés
CALayer* layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 200, 200);
layer.backgroundColor = [[UIColor redColor] CGColor];
[self.view.layer addSublayer:layer];
layer.frame = CGRectMake(100, 100, 200, 200);
En pratique
Appliquer des animations implicites à des
layers qui viennent d’être ajoutés
CALayer* layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 200, 200);
layer.backgroundColor = [[UIColor redColor] CGColor];
[self.view.layer addSublayer:layer];
[CATransaction flush];
layer.frame = CGRectMake(100, 100, 200, 200);
En pratique
Faire un rendu dans un contexte en
background et nettoyer derrière soi
CALayer* layer = ...;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
UIGraphicsBeginImageContext(layer.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[layer renderInContext:context];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_sync(dispatch_get_main_queue(), ^{
[self useImage:image];
});
});
En pratique
Faire un rendu dans un contexte en
background et nettoyer derrière soi
CALayer* layer = ...;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
UIGraphicsBeginImageContext(layer.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[layer renderInContext:context];
[CATransaction flush];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_sync(dispatch_get_main_queue(), ^{
[self useImage:image];
});
});
En pratique ?
Faire un rendu dans un contexte en
background et nettoyer derrière soi
CALayer* layer = ...;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
[CATransaction lock];
UIGraphicsBeginImageContext(layer.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[layer renderInContext:context];
[CATransaction unlock];
[CATransaction flush];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_sync(dispatch_get_main_queue(), ^{
[self useImage:image];
});
});
Questions ?
• Ressources
• WWDC videos
• Core Animation Programming Guide
@amadour

CocoaHeads Paris - CATransaction: What the flush?!