ios - Custom Interactive transition with CABasicAnimation(CAAnimation) -


i want build interactive transition uiviewanimation.but there's few layer property can animate it.so decided use caanimation. wanna change viewcontroller's view mask,here code

-(nstimeinterval)transitionduration:(nullable id<uiviewcontrollercontexttransitioning>)transitioncontext{     return 0.5f; }   -(void)animatetransition:(nonnull id<uiviewcontrollercontexttransitioning>)transitioncontext{     _transitioncontext=transitioncontext;    uiviewcontroller *fromvc=    [transitioncontext viewcontrollerforkey:uitransitioncontextfromviewcontrollerkey];    uiviewcontroller *tovc=    [transitioncontext viewcontrollerforkey:uitransitioncontexttoviewcontrollerkey];    uiview *containerview=[transitioncontext containerview];     _tovc=tovc;    _fromvc=fromvc;    [containerview insertsubview:tovc.view abovesubview:fromvc.view];     //create bezierpath    uibezierpath *initailpath=[uibezierpath bezierpathwithrect:(cgrect)  {{_cellrect.size.width/2,_cellrect.origin.y+_cellrect.size.height/2},.size= {0.5,0.5}}];    cgfloat radius;    cgfloat distance;    if (fromvc.view.frame.size.width>fromvc.view.frame.size.height) {        distance=fromvc.view.frame.size.width-_cellrect.origin.x;        radius=distance>_cellrect.origin.x?distance:_cellrect.origin.x+88;    }else{        distance=fromvc.view.frame.size.height-_cellrect.origin.y;        radius=distance>_cellrect.origin.y?distance:_cellrect.origin.y+88;    }    radius=radius*2;    uibezierpath *finalpath=[uibezierpath   bezierpathwithovalinrect:cgrectinset(_cellrect,                                                                            -  radius,                                                                            - radius)];    _initaialpath=initailpath;    _finalpath=finalpath;    //create layer mask    _masklayer=[[cashapelayer alloc] init];    _masklayer.path=finalpath.cgpath;    tovc.view.layer.mask=_masklayer;      [self animatelayer:_masklayer withcompletion:^{         bool iscomple=![transitioncontext transitionwascancelled];        if (!iscomple) {             [containerview addsubview:fromvc.view];            [tovc.view removefromsuperview];        }        [transitioncontext completetransition:iscomple];    }];   } -(void)startinteractivetransition:(nonnull id<uiviewcontrollercontexttransitioning>)transitioncontext{     _transitioncontext=transitioncontext;    [self animatetransition:transitioncontext];    [self pausetime:[_transitioncontext containerview].layer];  } 

this main animation,it work without interactive. tried control these code:

-(void)updateinteractivetransition:(cgfloat)percentcomplete{    [_transitioncontext updateinteractivetransition:percentcomplete];    [_transitioncontext containerview].layer.timeoffset=_pausedtime + [self transitionduration:_transitioncontext]*percentcomplete; }  -(void)finishinteractivetransition{     [_transitioncontext finishinteractivetransition];    [self resumetime:[_transitioncontext containerview].layer]; } 

these 2 functions work perfectly

buthere problem "cancel transition" when cancel transition disappear (i have tried solution in question that's not work me) here code:

- (void)cancelinteractivetransition {    //must cancel system interactivetransition frist    [_transitioncontext cancelinteractivetransition];    //then adjust layer time    calayer *masklayer =[_transitioncontext containerview].layer;    masklayer.begintime = cacurrentmediatime();    //most important    [uiview animatewithduration:0.5 animations:^{         masklayer.timeoffset=0.0;     } completion:^(bool finished) {         [[_transitioncontext containerview ] addsubview:_fromvc.view];        [_tovc.view removefromsuperview];    }]; 

}

now spend whole week on this, if can me predicate that.

we can animate layer's property initial value final value. when want implement interactive animation, can use uiview's animation block reach this(go final position or original position). can not property backgroundcolour,cgpath.

acturlly can control process using caanimation, , control timeoffset of calayer. when control animation process in precise position. how can make animation process? if property controlled position.

    [uiview animatewithduration:/*left time*/                            delay:/*delay time*/                    usingspringwithdamping:/*damping*/            initialspringvelocity:/*speed*/                          options:/*option*/                       animations:^{                          /*your animation*/                     } completion:^(bool finished) {      }]; 

but it's not suitable cgpath or backgroundcolor.

we need way drive animation, apple have supported driver, driver call function,that specified.and perform 60times per second iphone screen. tech cadisplaylink object. timer object allows application synchronise drawing refresh rate of display.

then got solution:

if (!_displaylink) {     _displaylink=[cadisplaylink displaylinkwithtarget:self selector:@selector(animationtick:)];     [_displaylink addtorunloop:[nsrunloop mainrunloop] formode:nsrunloopcommonmodes]; } 

animationtick function function refresh:

-(void)animationtick:(cadisplaylink *)displaylink{    calayer *masklayer=[_transitioncontext containerview].layer;   cgfloat timeoffset=masklayer.timeoffset;   timeoffset=max(0,timeoffset-_picedistance);   masklayer.timeoffset=timeoffset;   if (timeoffset==0) {       displaylink.paused=yes;   } } 

that's all


Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

jquery - javascript onscroll fade same class but with different div -