美文网首页
iOS 模态动画3

iOS 模态动画3

作者: 马大俊不是啥好人 | 来源:发表于2017-11-09 10:41 被阅读80次

    效果:


    11月-09-2017 10-22-43.gif

    主要用到了物理引擎。

    新建动画类MJAinimationRect
    在头文件中声明下面两个属性,一个是动画上下文,一个是物理引擎

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    @interface MJAnimationRect : NSObject<UIViewControllerAnimatedTransitioning,UICollisionBehaviorDelegate>
    @property (strong , nonatomic) id < UIViewControllerContextTransitioning > transitionContext;
    @property (nonatomic, strong) UIDynamicAnimator *animator;
    @end
    

    在实现文件中完成两个代理相对应该实现的代理方法

    动画过度时间,直接返回时间值

    -(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
    {
        return 2.0f;
    }
    

    之后准备实现动画效果,代码如下
    1.通过上下文获取跳转的view
    2.将fromVC截图
    3.调用cutView方法将截图切成4*5点格子并添加到当前的containerView上
    4.添加之前随机对切图进行微角度旋转,以增加动画效果
    5.获取目标view并添加到界面,置于页面底部,暂时先把他的alpha置为0
    6.添加作用力
    7.设置碰撞检测

    -(void)AnimationAnimationType:(id<UIViewControllerContextTransitioning>)transitionContext andToVC:(UIViewController*)toVC andFromVC:(UIViewController*)fromVC
    {
        UIView *containerView = [transitionContext containerView];
        UIView *mainSnap = [fromVC.view snapshotViewAfterScreenUpdates:NO];
        NSMutableArray* cutViewArray = [self cutView:mainSnap intoSlicesOfWidth:mainSnap.frame.size.width/kwidthCount andHeight:mainSnap.frame.size.height/kHeightCount];
        for (int i=0; i<cutViewArray.count; i++) {
            UIView* cutView = (UIView*)cutViewArray[i];
            
            CGFloat angle = (i% 2 ? 1 : -1) * (rand() % 5 / 10.0);
            cutView.transform = CGAffineTransformMakeRotation(angle);
            [containerView addSubview:cutView];
        }
        UIView* toView = [toVC view];
        toView.frame = [transitionContext finalFrameForViewController:toVC];
        [containerView addSubview:toView];
        [containerView sendSubviewToBack:toView];
        toView.alpha = 0;
        
        //截图已经覆盖fromView.view 所以可以直接隐藏。
        fromVC.view.hidden = YES;
    
        self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:containerView];
        UIDynamicBehavior *behaviour = [[UIDynamicBehavior alloc] init];
        //为每个view添加重力
        UIGravityBehavior* gravity = [[UIGravityBehavior alloc] initWithItems:cutViewArray];
        gravity.gravityDirection = CGVectorMake(0, 1); // 方向
        gravity.magnitude = 5; //加速度
        // 碰撞检测
        UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:cutViewArray];
        // 设置不要出边界,碰到边界会被反弹
        collision.translatesReferenceBoundsIntoBoundary = YES;
        collision.collisionDelegate = self;
        //除了边界碰撞没有其他碰撞
        collision.collisionMode = UICollisionBehaviorModeBoundaries;
        [behaviour addChildBehavior:gravity];
        [behaviour addChildBehavior:collision];
        
        //每个view设置不同的动画效果,添加到总的动作中去
        for (UIView *aView in cutViewArray) {
            UIDynamicItemBehavior *itemBehaviour = [[UIDynamicItemBehavior alloc] initWithItems:@[aView]];
            itemBehaviour.elasticity = (rand() % 5) / 8.0;
            itemBehaviour.density = (rand() % 5 / 3.0);
                    itemBehaviour.allowsRotation = YES;
            [behaviour addChildBehavior:itemBehaviour];
        }
        [self.animator addBehavior:behaviour];
        
        [UIView animateWithDuration:2 animations:^{
            for (UIView *aView in cutViewArray) {
                aView.alpha = 0.0;
                toView.alpha = 1;
            }
        } completion:^(BOOL finished) {
            for (UIView *view in cutViewArray) {
                [view removeFromSuperview];
            }
            [cutViewArray removeAllObjects];
            fromVC.view.hidden = NO;
            [transitionContext completeTransition:YES];
        }];
        
    }
    
    -(NSMutableArray *)cutView:(UIView *)view intoSlicesOfWidth:(float)width andHeight:(float)height{
        NSMutableArray *lineViews = [NSMutableArray array];
        UIView *subsnapshot;
        for (int x=0; x<CGRectGetWidth(view.frame); x+=width) {
            for (int y=0;y<CGRectGetHeight(view.frame); y+=height) {
                CGRect subrect = CGRectMake(x, y, width, height);
                subsnapshot = nil;
                subsnapshot = [view resizableSnapshotViewFromRect:subrect afterScreenUpdates:YES withCapInsets:UIEdgeInsetsZero];
                subsnapshot.frame = subrect;
                [lineViews addObject:subsnapshot];
            }
        }
        return lineViews;
    }
    

    之后在另外一个代理方法中调用该方法

    -(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
    {
        self.transitionContext = transitionContext;
        UIViewController* toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        UIViewController* fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        [self AnimationAnimationType:transitionContext andToVC:toVC andFromVC:fromVC];
    }
    
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
        [self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
        [self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
        [self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
    }
    

    调用方法,import 该类

    实现以下方法即可

    //返回一个管理动画过渡的对象
    -(nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
    {
        if (!self.animationRect) {
            self.animationRect = [MJAnimationRect new];
        }
        return self.animationRect;
    }
    
    - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
        if(!self.animationRect){
            self.animationRect = [[MJAnimationRect alloc] init];
        }
        return self.animationRect;
    }
    

    相关文章

      网友评论

          本文标题:iOS 模态动画3

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