ios - UIView animations with autoreverse -
i have problem setting uiviewanimationoptionautoreverse
. here code.
calayer *anilayer = act.viewtochange.layer; [uiview animatewithduration:2.0 delay:1.0 options:(uiviewanimationcurvelinear | uiviewanimationoptionautoreverse) animations:^{ viewtoanimate.frame = gcrectmake(1,1,100,100); [anilayer setvalue:[nsnumber numberwithfloat:degreestoradians(34)] forkeypath:@"transform.rotation"]; } completion:nil ];
the problem that, after animation has reversed, view jumps frame set in animation block. want view grow , "ungrow" , stop @ original position.
is there solution without programming 2 consecutive animations?
you have 3 options.
when use -[uiview animatewithduration:…]
methods, changes make in animations
block applied views in question. however, there implicit caanimation
applied view animates old value new value. when caanimation
active on view, changes displayed view, not change actual properties of view.
for example, if this:
nslog(@"old center: %@", nsstringfromcgpoint(someview.center)); [uiview animatewithduration:2.0 animations: ^{ someview.center = newpoint; }]; nslog(@"new center: %@", nsstringfromcgpoint(someview.center));
you see 'old center' , 'new center' different; new center immediately reflect values of newpoint. however, caanimation
implicitly created cause view still displayed @ old center , smoothly move way new center. when animation finishes, removed view , switch seeing actual model values.
when pass uiviewanimationoptionautoreverse
, affects implicitly created caanimation
, not affect actual change you're making values. is, if our example above had uiviewanimationoptionautoreverse
defined, implicitly created caanimation
animate oldcenter newcenter , back. animation removed, , we'd switch seeing values set… which still @ new position.
as said, there 3 ways deal this. first add completion block on animation reverse it, so:
first option
cgpoint oldcenter = someview.center; [uiview animatewithduration:2.0 animations: ^{ someview.center = newpoint; } completion: ^(bool finished) { [uiview animatewithduration:2.0 animations:^{ someview.center = oldcenter; }]; }];
second option
the second option autoreverse animation you're doing, , set view original position in completion block:
cgpoint oldcenter = someview.center; [uiview animatewithduration:2.0 delay:0 options: uiviewanimationoptionautoreverse animations: ^{ someview.center = newpoint; } completion: ^(bool finished) { someview.center = oldcenter; }];
however, may cause flickering between time animation autoreverse completes , when completion block runs, it's not best choice.
third option
the last option create caanimation
directly. when don't want change final value of property you're changing, simpler.
#import <quartzcore/quartzcore.h> cabasicanimation *animation = [cabasicanimation animationwithkeypath:@"position"]; animation.autoreverses = yes; animation.repeatcount = 1; // play once, , reverse animation.tovalue = [nsvalue valuewithcgpoint:newpoint]; [someview.layer addanimation:animation forkey:nil];
note caanimation
way of doing things never changes actual values of view; masks actual values animation. view still thinks it's in original location. (this means, example, if view responds touch events, still watching touch events happen @ original location. animation only changes way view draws; nothing else.
the caanimation
way requires add view's underlying calayer
. if scares you, feel free use -[uiview animatewithduration:…]
methods instead. there's additional functionality available using caanimation
, if it's you're not familiar with, chaining uiview animations or resetting in completion block acceptable. in fact, that's 1 of main purposes of completion block.
so, there go. 3 different ways reverse animation , keep original value. enjoy!
Comments
Post a Comment