iOS-自定義交互式轉(zhuǎn)場動畫

自定義轉(zhuǎn)場動畫主要有以下步驟
  • 自定義導(dǎo)航欄
  • 自定義交互動畫
  • 通過UIPercentDrivenInteractiveTransition協(xié)議實(shí)現(xiàn)交互
自定義導(dǎo)航欄

自定義導(dǎo)航欄需要遵守<UINavigationControllerDelegate>協(xié)議,該協(xié)議主要有兩個協(xié)議方法:

// 該方法返回導(dǎo)航跳轉(zhuǎn)時的動畫,如果返回nil,則是系統(tǒng)默認(rèn)的跳轉(zhuǎn)動畫,并且通過operation來判斷當(dāng)前執(zhí)行push還是pop
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    return nil;
}
// 該方法返回自定義交互動畫,只有實(shí)現(xiàn)該協(xié)議,才能在跳轉(zhuǎn)時實(shí)現(xiàn)與用戶交互
-(id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
    return nil;
}
自定義跳轉(zhuǎn)動畫

自定義跳轉(zhuǎn)動畫需要遵守<UIViewControllerAnimatedTransitioning>協(xié)議,該協(xié)議主要實(shí)現(xiàn)下面的方法:

// 該方法返回動畫執(zhí)行的時間,transitionContext由系統(tǒng)獲取
-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.3;
}
// 通過該協(xié)議,獲取跳轉(zhuǎn)的兩個VC
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    [self animateTransition:transitionContext fromVC:fromVC toVC:toVC fromView:fromVC.view toView:toVC.view];
}
// 這是模仿系統(tǒng)導(dǎo)航跳轉(zhuǎn)的例子
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView{
    [[transitionContext containerView] addSubview:toView];
    if (_isPush) {
        [[transitionContext containerView] bringSubviewToFront:toView];
        toView.transform = CGAffineTransformMakeTranslation(-toView.bounds.size.width, 0);
    }
    else{
        [[transitionContext containerView] bringSubviewToFront:fromView];
    }
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        if (_isPush) {
            toView.transform = CGAffineTransformIdentity;
        }
        else{
            fromView.transform = CGAffineTransformMakeTranslation(-fromView.bounds.size.width, 0);
        }
    } completion:^(BOOL finished) {
        transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}
實(shí)現(xiàn)交互

自定義一個類,繼承自UIPercentDrivenInteractiveTransition,它遵守<UIViewControllerInteractiveTransitioning>協(xié)議,我們可以告訴它當(dāng)前轉(zhuǎn)場動畫進(jìn)行的百分比,它再來更新動畫的進(jìn)度。轉(zhuǎn)場動畫進(jìn)行的百分比可以通過手勢來計(jì)算

// 在view上加入pan手勢
UIPanGestureRecognizer *gesture = objc_getAssociatedObject(self.interactiveVC.view, (__bridge const void *)(kpanGestureKey));
    if (gesture) {
        [self.interactiveVC.view removeGestureRecognizer:gesture];
    }
    gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
    [self.interactiveVC.view addGestureRecognizer:gesture];
    objc_setAssociatedObject(self.interactiveVC.view, (__bridge const void *)(kpanGestureKey), gesture,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// 當(dāng)pan手勢移動,通過移動的距離來計(jì)算當(dāng)前跳轉(zhuǎn)動畫需要完成的百分比,當(dāng)手勢結(jié)束時,判斷動畫完成的百分比。如果>50%,finishInteractiveTransition完成跳轉(zhuǎn)動畫;如果<50%,cancelInteractiveTransition取消動畫,返回原樣
case UIGestureRecognizerStateChanged:
        CGFloat fraction = point.x / [[UIScreen mainScreen] bounds].size.width;
        fraction = fminf(fmaxf(fraction, 0.0), 1.0);
        self.shouldComplete = (fraction > 0.5);
        [self updateInteractiveTransition:fraction];
    break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
        self.interactioning = NO;
        if (!self.shouldComplete || pan.state == UIGestureRecognizerStateCancelled) {
            [self cancelInteractiveTransition];
        }
        else {
            [self finishInteractiveTransition];
        }
    break;
最后附上Demo的地址https://github.com/cdcyd/CommonControlsCollection
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容