IOS转场动画

作者: _Comma | 来源:发表于2017-01-09 17:16 被阅读275次

    最近项目做完了,就进入无休止的修改中了。也顺便在看swift。学到了两个转场动画,也给大家看看
    PS:其实我一直以为转场动画又难又不实用,哈哈

    转场动画1: (先看效果图)

    XXX.gif
    这种转场方式跟boss直聘的应该差不多,所有就收集了 屏幕快照 2017-01-09 下午4.52.28.png

    先说说建的类的用处吧: ViewController:第一个控制器 BViewController:push出来的第二个控制器 PushAnimateion:继承NSObject的工具类,用于修改push动画 PopAnimateion:继承NSObject的工具类,用于修改Pop动画
    下面给出ViewController里面代码和PushAnimateion里面具体代码,另外两个类似,只上截图。另外,ViewController的导航栏是在storyboard里面直接加的 ViewController .m:

    #import "ViewController.h"
    #import "BViewController.h"
    #import "PushAnimateion.h"
    
    @interface ViewController ()<UINavigationControllerDelegate>
    
    @end
    
    @implementation ViewController
    
    //这个控制器的代理一定要在viewWillAppear里面设置
    //因为每次push的时候控制器不会dealloc
    //所以如果写在viewDidLoad里面的话在pop回来的时候就不会再次执行代理,动画就会失效
    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        self.navigationController.delegate = self;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //设置背景图片
        self.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"4"].CGImage);
        
        self.navigationController.navigationBar.hidden = YES;
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        BViewController *view = [BViewController new];
        [self.navigationController pushViewController:view animated:YES];
    }
    
    //需要返回的是一个id类型的且遵循UIViewControllerAnimatedTransitioning协议的
    - (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                                animationControllerForOperation:(UINavigationControllerOperation)operation
                                                             fromViewController:(UIViewController *)fromVC
                                                               toViewController:(UIViewController *)toVC {
        //根据类型返回对应动画
        if (operation == UINavigationControllerOperationPush) {
            return [PushAnimateion new];
        }else {
            return nil;
        }
    }
    
    @end
    

    PushAnimateion里面代码:

    //这是.h里面的,要遵循这个协议,不然UINavigationControllerDelegate返回这个类的对象会报错,所以写在.h里面
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    @interface PushAnimateion : NSObject<UIViewControllerAnimatedTransitioning>
    
    @end
    
    //.m里面代码
    #import "PushAnimateion.h"
    
    #define WIDTH [UIScreen mainScreen].bounds.size.width
    #define HEIGHT [UIScreen mainScreen].bounds.size.height
    
    @interface PushAnimateion ()<CAAnimationDelegate>
    
    @property (nonatomic, retain) id<UIViewControllerContextTransitioning> transitionContext;
    
    @end
    
    @implementation PushAnimateion
    
    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
        return .5;
        
    }
    
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
        self.transitionContext = transitionContext;
        
        UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        
        [[transitionContext containerView] addSubview:fromVC.view];
        [[transitionContext containerView] addSubview:toVC.view];
        
        UIBezierPath *starPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, HEIGHT*0.5, WIDTH, 1)];
        UIBezierPath *endPath  = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, WIDTH, HEIGHT)];
        
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
        maskLayer.path = endPath.CGPath;
        toVC.view.layer.mask = maskLayer;
        
        CABasicAnimation *animate = [CABasicAnimation animationWithKeyPath:@"path"];
        animate.fromValue = (__bridge id _Nullable)(starPath.CGPath);
        animate.toValue = (__bridge id _Nullable)(endPath.CGPath);
        animate.duration = [self transitionDuration:transitionContext];
        animate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        animate.delegate = self;
        [maskLayer addAnimation:animate forKey:@"path"];
    }
    
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
        [self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
        
        [self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
        [self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
    }
    
    @end
    

    如果建的类名相同,可以直接把代码拖到项目里,代码都拷贝齐全的 下面给两张图片是BViewController的m文件和PopAnimateion的m文件。PopAnimateion的h文件里跟PushAnimateion里面是一样的,代码基本一样,可以复制过去直接用

    屏幕快照 2017-01-09 下午5.05.36.png 屏幕快照 2017-01-09 下午5.05.50.png
    该项目有一点点小bug,就是pop回来的时候会闪一下,求大神解决了告知,😄

    转场动画2:

    xx.gif

    这个效果是系统自带的动画,做的比较粗糙,需要使用的朋友可以自己再修复一下 这个比较简单,直接上代码然后说一下就好了

    rootViewController的.m里面代码

    #import "ViewController.h"
    #import "AViewController.h"
    #import "BViewController.h"
    
    @interface ViewController ()
    
    @property (nonatomic, assign) NSInteger currentChildNumber;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.currentChildNumber = 0;
        [self addChildViewController:[AViewController new]];
        [self addChildViewController:[BViewController new]];
        
        [self.view addSubview:self.childViewControllers.firstObject.view];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getNotification) name:@"push" object:nil];
    }
    
    - (void)getNotification {
        [self transitionFromViewController:self.currentChildNumber == 0 ? self.childViewControllers.firstObject : self.childViewControllers.lastObject
                          toViewController:self.currentChildNumber == 1 ? self.childViewControllers.firstObject : self.childViewControllers.lastObject
                                  duration:1
                                   options:self.currentChildNumber == 0 ? UIViewAnimationOptionTransitionFlipFromLeft : UIViewAnimationOptionTransitionFlipFromRight
                                animations:nil
                                completion:nil];
        self.currentChildNumber = (self.currentChildNumber + 1) % 2;
    }
    
    @end
    

    只需要另外新建两个控制器,在touchBegin里面发个通知,这里接收就OK

    需要代码的可以加群:515385179(群里都没有人,来点大神救救我吧😄)
    我是小白,有没有收徒的,我报名😂

    相关文章

      网友评论

        本文标题:IOS转场动画

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