• iOS 利用UIPresentationController自定义转场动画


    1. 系统默认modal出来的动画效果默认是从屏幕底部爬出来的

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

        secondVC *second = [[secondVC alloc] init];

      [self presentViewController:second animated:YES completion:nil];

    }

    2. 想自定义转场动画,首先设置 展示样式过渡代理

        secondVC *second = [[secondVC alloc] init];

        second.modalPresentationStyle = UIModalPresentationCustom;

        second.transitioningDelegate = self;

        [self presentViewController:second animated:YES completion:nil];

    3.实现过渡代理方法,告诉程序" 哪个对象管理控制器的展示 "

    - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source

    {

        return [[MYPresentationController alloc]initWithPresentedViewController:presented presentingViewController:presenting];

    }

    4.自定义UIPresentationController

    // MYPresentationController.h

    @interface MYPresentationController : UIPresentationController

    @end

    // MYPresentationController.m

    #import "MYPresentationController.h"

    @implementation MYPresentationController

    - (CGRect)frameOfPresentedViewInContainerView

    {  

      return CGRectMake(100, 100, 150, 300); //设置modal出来控制器的frame

    }

    // 下面这几个方法,监听Modal控制器时的各种状态

    - (void)presentationTransitionWillBegin

    {

        NSLog(@"presentationTransitionWillBegin"); 

    }

    - (void)presentationTransitionDidEnd:(BOOL)completed

    {

        NSLog(@"presentationTransitionDidEnd");

    }

    - (void)dismissalTransitionWillBegin

    {

        NSLog(@"presentationTransitionDidEnd");

    }

    - (void)dismissalTransitionDidEnd:(BOOL)completed

    {

        NSLog(@"dismissalTransitionDidEnd");

    }

    @end

    5. 到了第4步,也只是做到了自定义展示,可以监听展示的过程,可以设置展示的frame.

      要想实现自定义转场动画,可以考虑设置second.modalTransitionStyle,但是没有UIModalTransitionStyleCustom,是因为

        只要设置了UIModalPresentationCustom,也就相当于设置了"UIModalTransitionStyleCustom",要想实现自定义转场动画,只要实现相应的代理方法即可

        secondVC *second = [[secondVC alloc] init];

        second.modalPresentationStyle = UIModalPresentationCustom;

        second.transitioningDelegate = self;

      second.modalTransitionStyle = UIModalTransitionStyleCoverVertical; // 要实现自定义转场动画,不是在这里设置

        [self presentViewController:second animated:YES completion:nil];

    #pragma mark - 自定义转场动画的代理方法,两个,分别控制显示和消失

    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source

    {

        return self; // 简单处理,返回self,只要self遵守<UIViewControllerAnimatedTransitioning>协议

    }

    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed

    {

        return self;

    }

    6.实现<UIViewControllerAnimatedTransitioning>协议方法,下面两个协议方法是必须实现的

    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext{

        return 0.3;

    }

    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{

        UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

            toView.y = -toView.height;

            [UIView animateWithDuration:0.3 animations:^{

                toView.y = 0;

            } completion:^(BOOL finished) {

                [transitionContext completeTransition:YES]; //这个必须写,否则程序 认为动画还在执行中,会导致展示完界面后,无法处理用户的点击事件

            }];

    }

    这样就实现了modal出来的控制器,是从屏幕顶部下来的转场动画

    7. 要实现 控制器消失时的动画,怎么办

    7.1 新增一个类,该类遵守<UIViewControllerAnimatedTransitioning>,新增一个属性,用来区别 显示或消失

    // MYAnimatedTransition.h

    @interface MYAnimatedTransition : NSObject<UIViewControllerAnimatedTransitioning>

    @property (assign,nonatomic) BOOL show;

    @end

    // MYAnimatedTransition.m

    @implementation MYAnimatedTransition

    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext

    {

        return 0.3;

    }

    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext

    {

        if (self.show == YES) { // 显示  

            UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

            toView.y = -toView.height;

            [UIView animateWithDuration:0.3 animations:^{

                toView.y = 0;

            } completion:^(BOOL finished) {

                [transitionContext completeTransition:YES];

            }];    

        }else{  // 消失      

            UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];

            [UIView animateWithDuration:0.3 animations:^{

                fromView.y = fromView.height;

            } completion:^(BOOL finished) {

                [transitionContext completeTransition:YES];

            }];

        }

    }

    @end

    7.2 修改自定义转场动画的代理方法,返回MYAnimatedTransition类对象

    #pragma mark - 自定义转场动画的代理方法,两个,分别控制显示和消失

    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source

    {

        MYAnimatedTransition *anima = [[MYAnimatedTransition alloc]init];

        anima.show = YES;

        return anima;

    }

    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed

    {

        MYAnimatedTransition *anima = [[MYAnimatedTransition alloc]init];

        anima.show = NO;

        return anima;

    }

    7.3 修改自定义UIPresentationController的.m文件

    - (void)presentationTransitionWillBegin{

        NSLog(@"presentationTransitionWillBegin");

        [self.containerView addSubview:self.presentedView]; // 因为是自定义转场动画,所以添加视图的工作也需要自行实现

    }

    - (void)dismissalTransitionDidEnd:(BOOL)completed

    {

        NSLog(@"dismissalTransitionDidEnd");

        [self.presentedView removeFromSuperview]; // 因为是自定义转场动画,所以移除视图的工作也需要自行实现

    }

    而且下面这个方法作废了,程序是不会执行的,因为你是自定义转场动画,动画前后的Frame都已经在这个方法实现了: - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext

    - (CGRect)frameOfPresentedViewInContainerView

    {  

      return CGRectMake(100, 100, 150, 300); 

    }

    7.4 要实现更复杂的转场动画,只要改下面这个方法,比如改成3D旋转

    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext

    {

            UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

            // toView.y = -toView.height;

            toView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0);

            [UIView animateWithDuration:0.3 animations:^{

                // toView.y = 0;

                toView.layer.transform = CATransform3DIdentity;

            } completion:^(BOOL finished) {

                [transitionContext completeTransition:YES];

            }];

            

        }else{

            

            UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];

            [UIView animateWithDuration:0.3 animations:^{

                   // fromView.y = fromView.height;

                   fromView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0);

            } completion:^(BOOL finished) {

                [transitionContext completeTransition:YES];

            }];

        }

    }

  • 相关阅读:
    PTA 7-9 空心字母金字塔 (10分)【待优化】
    PTA 7-12 交换最小值和最大值 (15分)
    PTA 7-8 分队列 (10分)
    PTA 7-6 计算阶乘和 (10分)
    PTA 7-5 得分计算器 (20分)
    PTA 7-4 有重复的数据 (10分)
    PTA 7-1 数组元素循环右移问题 (20分)
    PTA 7-1 换硬币 (20分)
    PTA 7-6 又来一个上三角数字三角形 (10分)【待完善】
    PTA 7-5 画菱形 (10分)
  • 原文地址:https://www.cnblogs.com/oumygade/p/4280512.html
Copyright © 2020-2023  润新知