美文网首页
转场动画

转场动画

作者: 小赤焰 | 来源:发表于2016-11-15 17:46 被阅读0次

    总结---present/dismiss

    modal presentation style

    这个枚举在iphone上常用的只有三个:fullScreen, overFullScreen,custom。
    下面说明这三个的区别:
    先点一下,在转场过程中,系统会加入一个过渡控制器:UIPresentationController。
    在自定义转场的过程中,presentingView presentedView 会被add到过渡控制器的view上。
    然而,一个view只能有一个父视图,当他被add到过渡控制器上,前父视图自然不再持有它,这也就导致了会有返回产生黑屏的情况。

    • fullScreen:推出的视图会占满屏幕。动画结束后,过渡控制器会移除add到自身的presentingView。
    • overFullScreen:推出的视图不是占满屏幕,而且在presentedView的下方可以响应操作。动画结束后,过渡控制器会不会移除add到自身的presentingView。与上方相反。
    • custom:完全自定义。需要自定义实现过渡控制器(协议中的最后一个方法),一般继承自系统的UIPresentationController即可。同样不会移除presentingView

    UIViewControllerTransitioningDelegate

    vc.transitioningDelegate = self;
    vc.modalPresentationStyle = @"枚举";
    
    - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
    
    - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed;
    
    - (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator;
    
    - (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator;
    
    - (nullable UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(nullable UIViewController *)presenting sourceViewController:(UIViewController *)source
    

    自动驱动

    前两个方法需要返回遵守UIViewControllerAnimatedTransitioning的对象,继承自NSObject即可,下方是实现

    - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{
        return 0.5;
    }
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
        UIView *view = [transitionContext containerView];
        __block UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
        __block UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
        [view addSubview:fromView];
        [view addSubview:toView];
        //根据需求操作两个view即可。
        //[UIView animate....]  + view的位置只能是通过设置transForm来决定。
    }
    

    其中有个上下文变量 transitionContext 下方是key 。

    UIKIT_EXTERN UITransitionContextViewControllerKey const UITransitionContextFromViewControllerKey 
    UIKIT_EXTERN UITransitionContextViewControllerKey const UITransitionContextToViewControllerKey 
    
    UIKIT_EXTERN UITransitionContextViewKey const UITransitionContextFromViewKey 
    UIKIT_EXTERN UITransitionContextViewKey const UITransitionContextToViewKey 
    

    手势驱动器

    中间两个是需要返回遵守UIViewControllerInteractiveTransitioning的对象,继承自UIPercentDrivenInteractiveTransition即可
    在需要手势驱动的控制器上加上手势,在手势的selector中根据手势的状态调用下方的方法即可。
    第一个方法中的百分比:根据手势拖拽的距离/屏幕的宽度

    - (void)updateInteractiveTransition:(CGFloat)percentComplete;
    - (void)cancelInteractiveTransition;
    - (void)finishInteractiveTransition;
    

    自定义过渡控制器

    继承自UIPresentationController,有六个方法需要重写
    初始化方法、过渡器进入时、进入完成、消失时、消失完毕以及presentedView呈现的frame
    过渡器是特殊的控制器,自身并没有view。
    dimmingView是加在过渡器上的view,再加个手势备用。如果用户能够点击这个view,可以给予响应回馈。

    - (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController
    {
        if ((self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController])) {
            _dimmingView = [[UIView alloc] init];
            _dimmingView.backgroundColor = [UIColor clearColor];
            _dimmingView.alpha = 1;
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]bk_initWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) {
                if (self.touchDimmingView) {
                    self.touchDimmingView();
                }
            }];
            [_dimmingView addGestureRecognizer:tap];
        }
        return self;
    }
    - (void)presentationTransitionWillBegin
    {
        _dimmingView.frame = self.containerView.bounds;
        [self.containerView addSubview:_dimmingView];
        [self.containerView addSubview:self.presentedView];
    }
    - (void)presentationTransitionDidEnd:(BOOL)completed
    {
        if (!completed) {
            [_dimmingView removeFromSuperview];
        }
    }
    - (void)dismissalTransitionWillBegin
    {
        [UIView animateWithDuration:0.3 animations:^{
            _dimmingView.alpha = 0;
        }];
    }
    - (void)dismissalTransitionDidEnd:(BOOL)completed
    {
        if (completed) {
            [_dimmingView removeFromSuperview];
        }
    }
    -(CGRect)frameOfPresentedViewInContainerView
    {
        return self.presentContnetSize;
    }
    

    总结--push/pop

    第一个是手势驱动器,第二个是动画。
    实现:代理方法的实现与上方提到的基本一致。按需实现即可。

    - (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                             interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController;
    
    - (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                      animationControllerForOperation:(UINavigationControllerOperation)operation
                                                   fromViewController:(UIViewController *)fromVC
                                                     toViewController:(UIViewController *)toVC;
    

    相关文章

      网友评论

          本文标题:转场动画

          本文链接:https://www.haomeiwen.com/subject/wxllpttx.html