2017-05-30 1 views
0

J'ai eu quelques difficultés à animer l'opacité d'une grande quantité (centaines) de petites CALayers. J'utilisais Core Animation mais je suis allé jusqu'à utiliser CVDisplayLink pour améliorer cela. Ce que j'ai trouvé, c'est que le fait de séparer toutes ces couches et d'animer leurs opacités produit de très mauvaises performances. Dans le code de mise à jour d'affichage, je voudrais simplement faire:Les performances d'animation de centaines de changements CALayers en fonction de la hiérarchie

for layer in layersToAnimateIn { 
    layer.opacity = newOpacity 
} 

déplacement de toutes ces couches dans un contenant plus couche et animant son opacité semble gérer beaucoup mieux.

containingLayer.opacity = newOpacity 

Depuis que je traite avec la même quantité de couches dans chaque cas, et l'effet visuel est identique, quelqu'un pourrait-il expliquer pourquoi la performance change de façon spectaculaire? Le système se heurte évidemment à la modification de l'opacité de centaines de couches par rafraîchissement d'écran.

Répondre

1

Chaque modification apportée à l'arborescence des couches implique un coût en termes de performances: plus vous modifiez de couches dans une transaction, plus le travail que CA doit effectuer pour parcourir et mettre à jour son modèle de données est long. Si vous changez tout à la même opacité, alors l'approche sur laquelle vous avez atterri est la bonne - il suffit de changer l'opacité du supercalculateur.

Si vous devez définir un ensemble de propriétés de calque sur des valeurs différentes à la fois, assurez-vous de désactiver les animations implicites, sinon vous obtenez une animation automatique pour chaque propriété modifiée sur chaque calque coût de son propre. Cela est particulièrement important lorsque vous définissez la propriété à partir d'une minuterie ou d'un lien d'affichage: si vous définissez une propriété 30 fois en une seconde, vous créez 30 animations en ce moment, ce qui est ... pas bien, à dire le moins. Pour désactiver les animations implicites, enveloppez le code dans lequel vous définissez les propriétés d'une transaction, comme ceci:

CATransaction.begin() 
CATransaction.setDisableActions(true) 
    for layer in layersToAnimateIn { 
     // … 
    } 
CATransaction.commit() 
+0

Merci pour la perspicacité, Noah. Bon point sur les animations implicites, j'avais sauté dessus. Fait intéressant, cependant, quand je les ai désactivés, la performance est restée à peu près la même. Le problème doit avoir à voir avec le côté du modèle de données comme vous l'avez mentionné au début. – Ricky