美文网首页
oc自定义present,dismiss动画

oc自定义present,dismiss动画

作者: zcc_ios | 来源:发表于2018-04-02 22:32 被阅读14次

    今天在写项目的广告页,之前是用uiview写的广告页,但是由于没办法在广告页出现的时候隐藏statusBar,无奈想着只能通过控制器写广告页了,因为默认present页面消失的时候是向下退出比较丑,所以打算自定义下退出动画。

    刚看了几篇文章关于自定义动画的文章就总结下自定义动画,我这也只是抛砖引玉,写的比较基础,有空再写复杂的切换效果。

    既然是自定义控制器切换动画,那么就必须创建一个类并且这个类要继承
    UIViewControllerAnimatedTransitioning这个协议
    字面意思差不多就是 控制器过渡动画 协议

    先上效果图

    动画.gif

    这是.h文件

    #import <UIKit/UIKit.h>
    @interface PresentTransition : NSObject<UIViewControllerAnimatedTransitioning>
    @end
    

    遵守这个UIViewControllerAnimatedTransitioning协议后主要要实现两个方法:
    第一个方法:

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

    上面第一个方法主要是返回动画时常的没什么好讲的;

    第二个方法

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

    第二个方法就有意思了,注意context这个单词,说明这里包含我们需要做动画的很多东西

    通过transitionContext我们可以获取目标控制器

        UIViewController *toVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    

    源控制器

    UIViewController *fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    

    动画时间:

    NSTimeInterval duration = [self transitionDuration:transitionContext]
    

    还有最重要的 容器,有了容器view,控制器的view才有地方显示和实现动画

    UIView *containerView = [transitionContext containerView];
    

    我这里的present动画是 源控制器从大变小,目标控制器则从右往左覆盖。
    所以我这里需要拿到两个控制器的view

    UIView *fromView = fromVC.view;
    UIView *toView = toVC.view;
    
    //这行代码必须加 不然目标控制器的view都不会出现
    [containerView addSubview:toView];
    

    接下来就是实现动画

    [UIView animateWithDuration:duration animations:^{
            
            //        fromView.x = containerView.width * (1 - scale) / 2;
            //        fromView.y = containerView.height * (1 - scale) / 2;
            //        fromView.width = containerView.width * scale;
            //        fromView.height = containerView.height * scale;
            
            toView.x = containerView.x;
            fromView.transform = CGAffineTransformMakeScale(0.9, 0.9);
            
        } completion:^(BOOL finished) {
            fromView.transform = CGAffineTransformMakeScale(1, 1);
            [transitionContext completeTransition:YES];
        }];
    

    所以PresentTransition.m文件的代码就是

    #import "PresentTransition.h"
    @implementation PresentTransition
    
    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
        return 0.4;
    }
    
    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
        return 0.4;
    }
    
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    
        UIViewController *toVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        UIViewController *fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        
        UIView *containerView = [transitionContext containerView];
        NSLog(@"%@", containerView);
        UIView *fromView = fromVC.view;
        UIView *toView = toVC.view;
        
        toView.x = containerView.width;
        
        [containerView addSubview:toView];
        
        NSTimeInterval duration = [self transitionDuration:transitionContext];
        [UIView animateWithDuration:duration animations:^{
            
            //        fromView.x = containerView.width * (1 - scale) / 2;
            //        fromView.y = containerView.height * (1 - scale) / 2;
            //        fromView.width = containerView.width * scale;
            //        fromView.height = containerView.height * scale;
            
            toView.x = containerView.x;
            fromView.transform = CGAffineTransformMakeScale(0.9, 0.9);
            
        } completion:^(BOOL finished) {
            fromView.transform = CGAffineTransformMakeScale(1, 1);
            [transitionContext completeTransition:YES];
        }];
    }
    
    

    自定义动画到这里就结束了,接下来是怎么用:
    首先在源控制器.m 遵守协议,.h不变

    @interface ViewController ()<UIViewControllerTransitioningDelegate>
    

    然后实现方法 和 代理

    - (void)presentBtnClicked{
        
        ZCCSecondViewController *secondVC = [[ZCCSecondViewController alloc] init];
        secondVC.transitioningDelegate = self;//
        [self presentViewController:secondVC animated:YES completion:nil];
    }
    
    - (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
        
        PresentTransition *transition = [[PresentTransition alloc] init];
        transition.transitionType = ZCCTransitionTypePresent;
        return transition;
    }
    

    目标控制器操作 .m文件 这里我还写了返回来的动画 所以我目标控制器是这么写的

    
    @interface ZCCSecondViewController ()<UIViewControllerTransitioningDelegate>
    @end
    
    - (void)dismissClick{
        
        self.transitioningDelegate = self;
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
        PresentTransition *pushAnimation = [[PresentTransition alloc] init];
        pushAnimation.transitionType = ZCCTransitionTypeDismiss;
        return pushAnimation;
    }
    

    自定义动画的完整版代码如下

    .h文件

    #import <UIKit/UIKit.h>
    
    typedef NS_ENUM(NSUInteger, ZCCTransitionType){
        
        ZCCTransitionTypePresent = 0,
        ZCCTransitionTypeDismiss,
        ZCCTransitionTypePush,
        ZCCTransitionTypePop,
    };
    
    @interface PresentTransition : NSObject<UIViewControllerAnimatedTransitioning>
    
    @property (nonatomic, assign)ZCCTransitionType transitionType;
    
    @end
    

    .m文件

    //
    //  PresentTransition.m
    //  MOSOBOStudent
    //
    //  Created by 章程程 on 2018/4/2.
    //  Copyright © 2018年 zcc. All rights reserved.
    //
    
    #import "PresentTransition.h"
    #import "ZCCCommon.h"
    @implementation PresentTransition
    
    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
        return 0.4;
    }
    
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
        
        switch (_transitionType) {
            case ZCCTransitionTypePresent:
                {
                    [self presentAnimation:transitionContext];
                }
                break;
            case ZCCTransitionTypeDismiss:
                {
                    [self dismissAnimation:transitionContext];
                }
                break;
            case ZCCTransitionTypePush:
                {
                    
                }
                break;
            case ZCCTransitionTypePop:
                {
                    
                }
                break;
            default:
                break;
        }
        
    }
    
    - (void)presentAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
        
        UIViewController *toVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        UIViewController *fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        
        UIView *containerView = [transitionContext containerView];
        containerView.backgroundColor = [UIColor whiteColor];
        NSLog(@"%@", containerView);
        UIView *fromView = fromVC.view;
        UIView *toView = toVC.view;
        
        toView.x = containerView.width;
        
        [containerView addSubview:toView];
        
        NSTimeInterval duration = [self transitionDuration:transitionContext];
        [UIView animateWithDuration:duration animations:^{
            
            //        fromView.x = containerView.width * (1 - scale) / 2;
            //        fromView.y = containerView.height * (1 - scale) / 2;
            //        fromView.width = containerView.width * scale;
            //        fromView.height = containerView.height * scale;
            
            toView.x = containerView.x;
            fromView.transform = CGAffineTransformMakeScale(0.9, 0.9);
            
        } completion:^(BOOL finished) {
            fromView.transform = CGAffineTransformMakeScale(1, 1);
            [transitionContext completeTransition:YES];
        }];
    }
    
    - (void)dismissAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
        
        UIViewController *toVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        UIViewController *fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        
        UIView *containerView = [transitionContext containerView];
        NSLog(@"%@", containerView);
        UIView *fromView = fromVC.view;
        UIView *toView = toVC.view;
        
        [containerView addSubview:toView];
        
        [containerView bringSubviewToFront:fromVC.view];
        
        toView.transform = CGAffineTransformMakeScale(0.9, 0.9);
        
        NSTimeInterval duration = [self transitionDuration:transitionContext];
        
        [UIView animateWithDuration:duration animations:^{
            
            fromView.x = containerView.width;
            toView.transform = CGAffineTransformMakeScale(1.0, 1.0);
            
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
        
    }
        
    @end
    

    相关文章

      网友评论

          本文标题:oc自定义present,dismiss动画

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