iOS - 自定义转场动画

来源:互联网 发布:电脑模拟炒股软件 编辑:程序博客网 时间:2024/05/01 22:15

经常在项目中 , 我们会用到一些下拉菜单 , 或者上弹菜单等 . 简单的做法就是加一层蒙板 , 自定义一个view , 写一下动画就完成了 . 但是这样写的话 , 首先是比较low , 其次是性能略有损耗 , 且比较杂乱 . 其实在iOS中 , 如果是iPad开发的 , 苹果直接就有提供PopoVerController使用 . 如果是iPhone呢 , 也可以通过重写类 , 来实现

#import "ViewController.h"#import "MYShowAnimationController.h"#import "MYPresentationController.h"@interface ViewController ()<UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning>@property (assign, nonatomic) BOOL isOpen;//下拉菜单控制器@property (strong, nonatomic) MYShowAnimationController *showVc;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor whiteColor];    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];    [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];    [button setTitle:@"开始动画" forState:UIControlStateNormal];    button.frame = CGRectMake(275 *0.5,20,100, 44);    [self.view addSubview:button];    [button addTarget:self action:@selector(animationBegin) forControlEvents:UIControlEventTouchUpInside];    self.navigationItem.titleView = button;}- (void)animationBegin{    if (!self.isOpen) {    self.showVc = [[MYShowAnimationController alloc]init];    //设定模态风格 , custom可以保持容器下层的图层不被隐藏    self.showVc.modalPresentationStyle = UIModalPresentationCustom;    self.showVc.transitioningDelegate = self;    [self presentViewController:self.showVc animated:YES completion:^{        self.isOpen = YES;    }];    }else{    [self.showVc dismissViewControllerAnimated:YES completion:^{        [self.showVc.view removeFromSuperview];        self.showVc = nil;//        self.isOpen = NO;    }];    }}//代理方法:改变弹出控制器view的frame//返回自定义的容器控制器,我们自己来写它的布局- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source{    return [[MYPresentationController alloc]initWithPresentedViewController:presented presentingViewController:presenting];}// UIViewControllerTransitioningDelegate 协议中方法 , 自定义弹出动画 , 返回一个遵循 UIViewControllerAnimatedTransitioning 协议的控制器- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{    return self;}//消失动画- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{    return self;}//动画持续时间- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{    return 0.25;}//获取转场上下文 , 拿到presentedView 和 presentingView自定义动画- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{//    if (!self.isOpen) {////        //根据key值取出被模态视图view//        //   UITransitionContextToViewKey//        //   UITransitionContextFromViewKey//        UIView *presentedView = [transitionContext viewForKey:UITransitionContextToViewKey];////        //设置锚点 (从顶点中心弹出)//        presentedView.layer.anchorPoint = CGPointMake(0.5, 0);//        //        //添加被模态视图view到容器view中//        [[transitionContext containerView]addSubview:presentedView];//        NSLog(@"%@",presentedView);////        //执行动画//        presentedView.transform = CGAffineTransformMakeScale(1.0,0.001);//        [UIView animateWithDuration:0.25 animations:^{//            //            presentedView.transform = CGAffineTransformIdentity;//            //        }//                         completion:^(BOOL finished) {//            //            //告知动画已经执行完毕//            [transitionContext completeTransition:YES];//            self.isOpen = YES;//        }];//    }else{////        UIView *presentingView = [transitionContext viewForKey:UITransitionContextFromViewKey];////        //添加被模态视图view到容器view中//        [[transitionContext containerView]addSubview:presentingView];////        presentingView.transform = CGAffineTransformMakeScale(1.0,1.0);//        //执行动画//        [UIView animateWithDuration:0.25 animations:^{//            //            presentingView.transform = CGAffineTransformMakeScale(1.0,0.001);//            //        } completion:^(BOOL finished) {//            //            //告知动画已经执行完毕//            [transitionContext completeTransition:YES];//            self.isOpen = NO;//            //        }];//    }    if (!self.isOpen) {        //根据key值取出被模态视图view        //   UITransitionContextToViewKey        //   UITransitionContextFromViewKey        UIView *presentedView = [transitionContext viewForKey:UITransitionContextToViewKey];        //设置锚点 (从顶点中心弹出)        presentedView.layer.anchorPoint = CGPointMake(0.5, 0);        //添加被模态视图view到容器view中        [[transitionContext containerView]addSubview:presentedView];        NSLog(@"%@",presentedView);        //执行动画//        presentedView.transform = CGAffineTransformMakeScale(1.0,0.001);        presentedView.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - 200) *0.5, -300, 200, 300);        [UIView animateWithDuration:0.25 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:5 options:UIViewAnimationOptionCurveEaseIn animations:^{            presentedView.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - 200) *0.5, 0, 200, 300);        } completion:^(BOOL finished) {            [transitionContext completeTransition:YES];            self.isOpen = YES;        }];    }else{        UIView *presentingView = [transitionContext viewForKey:UITransitionContextFromViewKey];        //添加被模态视图view到容器view中        [[transitionContext containerView]addSubview:presentingView];        [UIView animateWithDuration:0.25 animations:^{            presentingView.transform = CGAffineTransformMakeScale(1.0, 0.001);        } completion:^(BOOL finished) {            [transitionContext completeTransition:YES];            self.isOpen = NO;        }];    }}

被模态类

#import "MYShowAnimationController.h"@interface MYShowAnimationController ()@end@implementation MYShowAnimationController- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor redColor]; }

模态时 容器view控制器

#import <UIKit/UIKit.h>//继承与 UIPresentationController@interface MYPresentationController : UIPresentationController@end--------------------------------------------------------#import "MYPresentationController.h"@interface MYPresentationController ()//蒙板@property (strong, nonatomic) UIControl *coverView;@end@implementation MYPresentationController//蒙板- (UIControl *)coverView{    if (!_coverView) {        _coverView = [[UIControl alloc]init];        _coverView.frame = CGRectMake(0,0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);        _coverView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];        [_coverView addTarget:self action:@selector(coverTouch) forControlEvents:UIControlEventTouchUpInside];    }    return _coverView;}//容器view即将布局- (void)containerViewWillLayoutSubviews{    [super containerViewWillLayoutSubviews];    //调整容器view大小    self.containerView.frame = (CGRect){0,64,[UIScreen mainScreen].bounds.size.width,[UIScreen mainScreen].bounds.size.height - 64};    //被模态出来控制器的view尺寸    CGFloat width = 200;    CGFloat height = 300;    CGFloat presentedViewX = ([UIScreen mainScreen].bounds.size.width - width) *0.5;    CGFloat presentedViewY = 0;    self.presentedView.frame = CGRectMake(presentedViewX,presentedViewY, width, height);    //添加蒙板在presentedView下面    [self.containerView insertSubview:self.coverView belowSubview:self.presentedView];}//蒙板点击方法- (void)coverTouch{    [UIView animateWithDuration:0.1 animations:^{        self.coverView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.001];        [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];    } completion:^(BOOL finished) {        [self.coverView removeFromSuperview];    }];}

还有很多有意思的动画 , 都可以实现 .当然也可以自行封装一下 ,以供今后使用 , 比如将返回self处改为 继承与NSObject类的对象 , 然后将所有代理方法封装与 该类中

简单效果如下 , 在showViewController中可以添加控件 , 比如常见的下拉tableView , collectionView , 九宫格按钮等等 .. .
这里写图片描述

0 0
原创粉丝点击