ios - How to wait for an repeating CAAnimation to finish a cycle before removing it -
i have view let pulsate using caanimation.
cakeyframeanimation *animation = [cakeyframeanimation animationwithkeypath:@"opacity"]; animation.values = @[ @0.0f, @1.0f, @0.0f ]; animation.duration = 0.5; animation.repeatcount = huge_valf; [view.layer addanimation:animation forkey:@"pulsate"]; when remove animation using [view.layer removeanimationforkey:@"pulsate"] opacity snaps immediately. achieve executing pulsating animation finished , animation removed.
i tried setting repeatcount 1, throws exception because animation immutable.
also tried getting current value presentation layer , applying model, removing animation , again adding animation finish it. gives noticeable hiccups when stopping animation , timing off usually.
is there way let animation finish running cycle , remove afterwards?
there's lot of details right, general idea create non-repeating animation removed on completion, , use animationdidstop delegate method restart animation.
the first item of business declare properties
@property (weak, nonatomic) iboutlet uiimageview *orangeview2; @property (nonatomic) bool pulseactive; @property (strong, nonatomic) cakeyframeanimation *pulseanimation; the first property view animated, second keeps track of whether animation enabled, , last actual animation (stored in property have instantiate once).
next, we'll use lazy instantiation create animation object
- (cakeyframeanimation *)pulseanimation { if ( !_pulseanimation ) { _pulseanimation = [cakeyframeanimation animationwithkeypath:@"opacity"]; _pulseanimation.values = @[ @0.0f, @1.0f, @0.0f ]; _pulseanimation.duration = 0.5; _pulseanimation.delegate = self; [_pulseanimation setvalue:@"pulseanimation" forkey:@"animationidentifier"]; } return( _pulseanimation ); } the important bits here
- the animation not repeat (by default)
- the animation
removedoncompletion(by default) - the
delegatesetselfanimationdidstopmethod called - the animation given identifier using
setvalue:forkey:
that last item needed if multiple animations using same delegate, since in case, you'll need way determine animation called animationdidstop. strings passed forkey , setvalue arbitrary, , stored in dictionary in animation object.
ok, need implement animationdidstop. implementation checks pulseactive property , restarts animation if necessary (after checking identity of animation).
- (void)animationdidstop:(caanimation *)animation finished:(bool)flag { nsstring *animationidentifier = [animation valueforkey:@"animationidentifier"]; if ( [animationidentifier isequaltostring:@"pulseanimation"] ) { if ( self.pulseactive ) [self.orangeview2.layer addanimation:self.pulseanimation forkey:@"pulsate"]; } } all that's left start , stop animation. example, button toggles animation
- (ibaction)pulsebuttonpressed { if ( !self.pulseactive ) { self.pulseactive = yes; [self.orangeview2.layer addanimation:[self pulseanimation] forkey:@"pulsate"]; } else { self.pulseactive = no; } }
Comments
Post a Comment