ios - animate a UIView using CADisplayLink 'combined' with CAMediaTimingFunction. (to get a arbitrary curve) -


i using cadisplaylink view animation interpolates value , redraws view itself.

e.g. have view myview , has property value, whenever value set call setneedsdisplay , view knows draw.

to animate use cadisplaylink , want view 'morph' between values. interpolating value animation's start , stop value:

- (cgfloat)interpolatedvalue:(cgfloat)sourcevalue withvalue:(cgfloat)targetvalue forprogress:(cgfloat)progress;

now getting linear progress easy , getting 'specific curve' (ok) want able take advantage of camediatimingfunction (or other preexisting logic - don't want reinvent wheel again' :)

there's awesome gist rstiming might handy in case. can define timing functions either using standard camediatimingfunction or define custom ones using 2 control points define bezier curve.

if got setup, may have this:

viewcontroller

#import "viewcontroller.h" #import "animatedview.h" #include <stdlib.h>  @interface viewcontroller ()  @property (nonatomic, strong) cadisplaylink *displaylink; @property (weak, nonatomic) iboutlet animatedview *viewtoanimate;  @end  @implementation viewcontroller  - (void)viewdidload {     [super viewdidload];      self.displaylink = [cadisplaylink displaylinkwithtarget:self selector:@selector(updateframe)];     [self.displaylink addtorunloop:[nsrunloop currentrunloop] formode:nsdefaultrunloopmode]; }  - (void)updateframe {     [self.viewtoanimate updateanimation]; }  - (ibaction)updateanimationtapped:(id)sender {     self.viewtoanimate.value = arc4random_uniform(101) / 100.0;     nslog(@"next animation value: %f", self.viewtoanimate.value); }  @end 

animatedview

#import "animatedview.h" #import "rstimingfunction.h"  @interface animatedview() {     cgfloat _lastvalue;     cgfloat _progressstep;     cgfloat _currentprogress; }  @property (nonatomic, strong) rstimingfunction *animationprogress;  @end  @implementation animatedview  - (instancetype)initwithcoder:(nscoder *)adecoder {     if ((self = [super initwithcoder:adecoder]))     {         _progressstep = 0.01; // defines animation speed         _currentprogress = 1.0;         self.animationprogress = [rstimingfunction timingfunctionwithname:krstimingfunctioneaseineaseout];     }      return self; }  - (void)setvalue:(cgfloat)value {     if (_value != value)     {         _lastvalue = _value;         _value = value;         _currentprogress = 0.0;     } }  - (void)updateanimation {     if (_currentprogress > 1.0)         return;      _currentprogress += _progressstep;     cgfloat currentanimationvalue = _lastvalue + (_value - _lastvalue) * [self.animationprogress valueforx:_currentprogress];      self.alpha = currentanimationvalue; // example animate alpha }  @end 

as said can set 2 control points create timing function modelled on cubic bezier curve.

self.animationprogress = [rstimingfunction timingfunctionwithcontrolpoint1:cgpointmake(0.6, 0.6) controlpoint2:cgpointmake(0.1, 0.8)]; 

which produce following timing animation (produced using camediatimingfunction playground)

enter image description here


Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -