ios observant le changement dans le cadre d'un UIView pendant l'animation

Je souhaite observer les modifications de la coordonnée x de l'origine de mon UIView qui est animée en utilisant animateWithDuration: delay: options: animations: completion. Je souhaite suivre les modifications de la coordonnée x au cours de cette animation à un niveau granulaire, car je souhaite modifier l'interaction avec une autre vue avec laquelle la vue animée peut entrer en contact. Je veux faire ce changement au sharepoint contact exact. Je veux comprendre la meilleure façon de faire quelque chose comme ça à un niveau supérieur:

– Dois-je animer la prochaine fois avec le timeout d'attente dans le callback d'achèvement au sharepoint contact? En d'autres termes, le premier animateWithDuration s'anime jusqu'à ce qu'il atteigne cette coordonnée x, et le rest de l'animation se déroule dans le callback de fin?

– Dois-je utiliser des observateurs NSNotification et observer les modifications apscopes à la propriété frame? Comment précis / granulaire est-ce? Puis-je suivre chaque changement de x? Dois-je le faire dans un fil séparé?

Toute autre suggestion serait la bienvenue. Je suis à la search d'une meilleure pratique.

Utilisez CADisplayLink car il est spécialement conçu à cet effet. Dans la documentation, il est dit:

Une fois que le lien d'affichage est associé à une boucle d'exécution, le sélecteur sur la cible est appelé lorsque le contenu de l'écran doit être mis à jour.

Pour moi, j'avais une barre qui se remplissait, et comme elle passait une certaine marque, je devais changer les colors de la vue au-dessus de cette marque.

C'est ce que j'ai fait:

 let displayLink = CADisplayLink(target: self, selector: #selector(animationDidUpdate)) displayLink.frameInterval = 3 displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode) UIView.animateWithDuration(1.2, delay: 0.0, options: [.CurveEaseInOut], animations: { self.viewGaugeGraph.frame.size.width = self.graphWidth self.imageViewGraphCoin.center.x = self.graphWidth }, completion: { (_) in displayLink.invalidate() }) func animationDidUpdate(displayLink: CADisplayLink) { let presentationLayer = self.viewGaugeGraph.layer.presentationLayer() as! CALayer let newWidth = presentationLayer.bounds.width switch newWidth { case 0 ..< width * 0.3: break case width * 0.3 ..< width * 0.6: // Color first mark break case width * 0.6 ..< width * 0.9: // Color second mark break case width * 0.9 ... width: // Color third mark break default: fatalError("Invalid value observed. \(newWidth) cannot be bigger than \(width).") } } 

Dans l'exemple, j'ai mis la propriété frameInterval à 3 car je n'avais pas à mettre à jour rigoureusement. La valeur par défaut est 1 et cela signifie qu'il se triggersra pour chaque image, mais cela réduira les performances.

créer un NSTimer avec un certain retard et exécuter un sélecteur particulier après chaque intervalle de time.
Dans cette méthode, vérifiez l'image animée et comparez-la avec votre vue en collision.

Et assurez-vous que vous utilisez frame de presentationLayer car si vous accédez à view.frame pendant l'animation, cela donne le cadre de destination qui est constant tout au long de l'animation.

 CGRect animationViewFrame= [[animationView.layer presentationLayer] frame]; 

Si vous ne voulez pas créer de timer, write a selector which calls itself after some delay Gagnez environ 0,01 secondes.

CLARIFICATION ->
Disons que vous avez une vue dont vous animer sa position de (0,0) à (100,100) avec une durée de 5secs. Supposons que vous avez implémenté KVO dans le cadre de cette vue

Lorsque vous appelez le animateWithDuration block , la position de la vue passe directement à (100,100), valeur finale même si la vue se déplace avec des valeurs de position intermédiaires.

Ainsi, votre KVO sera viré une fois au moment du début de l'animation . Parce que les calques ont une layer Tree et Presentation Tree . Alors que l' layer tree stocke uniquement les valeurs de destination alors que la presentation Layer stocke les valeurs intermédiaires.
Lorsque vous accédez à view.frame il donne toujours la valeur de l'image dans l' layer tree non les images intermédiaires qu'elle prend.

Donc, vous avez dû utiliser le presentation Layer frame pour get des images intermédiaires.

J'espère que cela t'aides.

UIDynamics et les comportements de collision mériteraient d'être étudiés ici. Vous pouvez définir un délégué qui est appelé lorsqu'une collision se produit.

Voir la documentation sur le comportement de collision pour plus de détails.