zoukankan      html  css  js  c++  java
  • iOS:自定义模态动画 --UIPresentationController

    UIPresentationController :展示控制器,是iOS8的一个新特性,用来展示模态窗口的。它是所有模态控制器的管理者。

    即:

    1> 管理所有Modal出来的控制器

    2> 管理所有通过- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion方法显示出来的控制器

    3> 管理监听切换控制器的过程

    4> presentingViewController:后面的控制器

    5> presentedViewController:前面的控制器

    6> presentedView:前面的控制器的view

     

    注意:

    1.只要调用了[self presentViewController: animated: completion:]方法

    2.首先会创建一个UIPresentationController

    3.然后由UIPresentationController管理控制器的切换

    拓展:

    1、系统给定的集中模态动画展示样式modalPresentationStyle有如下几种:

    typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {

            UIModalPresentationFullScreen = 0,

            UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2),

            UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2),

            UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2),

            UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0),

            UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0), 

            UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0),

            UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0),

            UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1, 

    };

    2、系统给定的集中模态动画过渡样式modalTransstionStyle有如下几种:

     typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {

        UIModalTransitionStyleCoverVertical = 0,

        UIModalTransitionStyleFlipHorizontal,

        UIModalTransitionStyleCrossDissolve,

        UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2),

    };

    由于给定的东西毕竟有限,有的时候不能满足自己需要的动画效果,此时我们可以自己自定义modal动画,做出炫目的动画。

    过程:其实做自定义的modal动画还是比较复杂的,因为我既需要自定义动画展示样式类,也需要自定义动画过渡样式类,并且要实现这两个类对应的协议,设置过渡代理,然后实现协议方法。

    下面就是具体的实例,自定义modal动画:

    导入必要的第三方源文件,方便后面代码的复用

    在故事板中设置ViewController控制器的视图颜色

    创建一个secondViewController.h/.m/.xib文件,设置视图颜色

    创建自定义的动画展示样式类CustomPresentationController.h/.m文件,直接继承自UIPresentationController

    .h文件:

    #import <UIKit/UIKit.h>
    
    @interface CustomPresentationController : UIPresentationController
    
    @end

    .m文件:重写下面的几个方法

    #import "CustomPresentationController.h"
    
    @implementation CustomPresentationController
    
    
    //可以改变被模态的控制器视图的尺寸
    //- (CGRect)frameOfPresentedViewInContainerView
    //{
    //    
    //    /**  containerView是容纳presentedView的一个容器  */
    //    //return CGRectMake(0,50,self.containerView.frame.size.width,self.containerView.frame.size.height-100);
    //    
    //    return CGRectInset(self.containerView.bounds, 0, 50);
    //}
    
    //过渡即将开始时的处理
    - (void)presentationTransitionWillBegin
    {
        self.presentedView.frame = self.containerView.frame;
        [self.containerView addSubview:self.presentedView];
    }
    
    
    - (void)presentationTransitionDidEnd:(BOOL)completed
    {
         
    }
    - (void)dismissalTransitionWillBegin
    {
        
    }
    
    //过渡消失时的处理
    - (void)dismissalTransitionDidEnd:(BOOL)completed
    {
        [self.presentedView removeFromSuperview];
    }
    @end

    创建自定义的动画过渡样式类CustomAnimationTransition.h/.m文件,实现UIViewControllerAnimatedTransitioning协议

    .h文件:

    #import <UIKit/UIKit.h>
    
    @interface CustomAnimationTransition : NSObject<UIViewControllerAnimatedTransitioning>
    @property (assign,nonatomic)BOOL presented;
    @end

    .m文件:主要实现下面这两个方法来设置自己需要的动画过渡

    #import "CustomAnimationTransition.h"
    #import "UIView+Extension.h"
    
    const CGFloat duration = 1.0f;
    
    @implementation CustomAnimationTransition
    
    
    #pragma mark -<UIViewControllerAnimatedTransitioning>
    //动画时间
    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
    {
        return duration;
    }
    //设置过渡动画(modal和dismiss的动画都需要在这里处理)
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
    {
        // UITransitionContextToViewKey,
        // UITransitionContextFromViewKey.
        
        //出来的动画
        if (self.presented) {
            
            UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
            //toView.y = -toView.height;  //设置动画从上往下进来
            toView.x = toView.width;      //设置动画从右往左进来
            
            //设置动画3D旋转
            //toView.layer.transform = CATransform3DMakeRotation(M_PI_2, 1, 1, 0);
            
            [UIView animateWithDuration:duration animations:^{
                
                //toView.y = 0;
                toView.x = 0;
                
                //toView.layer.transform = CATransform3DIdentity;
                
            } completion:^(BOOL finished) {
                
                //动画完成后,视图上的事件才能处理
                [transitionContext completeTransition:YES];
            }];
        }
        //销毁的动画
        else
        {
            [UIView animateWithDuration:duration animations:^{
                
                UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
                
                //fromView.y = -fromView.height;
                fromView.x = -fromView.width;     //从右往左出去
                
                //fromView.layer.transform = CATransform3DMakeRotation(M_PI_2, 1, 1, 0);
                
            } completion:^(BOOL finished) {
                
                //动画完成后,视图上的事件才能处理
                [transitionContext completeTransition:YES];
            }];
        }
        
    }
    @end

    创建一个单例的动画类,将ViewController控制器类中实现的UIViewControllerTransitionDelegate协议的方法全部在该类Transition.m文件中实现,主控制器只需要创建这个单例类对象并将它设置为代理即可。

    .h文件:

    #import <UIKit/UIKit.h>
    #import "Singleton.h"
    
    
    @interface Transition : NSObject<UIViewControllerTransitioningDelegate>
    SingletonH(Transition);
    @end

    .m文件:返回动画展示样式和动画过渡样式

    #import "Transition.h"
    #import "CustomPresentationController.h"
    #import "CustomAnimationTransition.h"
    
    @implementation Transition
    SingletonM(Transition);
    
    
    #pragma mark - <UIViewControllerTransitioningDelegate>
    //返回展示样式
    -(UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
    {
        return [[CustomPresentationController alloc]initWithPresentedViewController:presented presentingViewController:presenting];
    }
    
    //展示的动画
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
    {
        CustomAnimationTransition *animation = [[CustomAnimationTransition alloc]init];
        animation.presented = YES;
        return animation;
    }
    
    //关闭时的动画
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
    {
        CustomAnimationTransition *animation = [[CustomAnimationTransition alloc]init];
        animation.presented = NO;
        return animation;
    }
    @end

    在ViewController的.m文件中实现动画测试如下:

    #import "ViewController.h"
    #import "SecondViewController.h"
    #import "UIView+Extension.h"
    #import "Transition.h"
    
    @interface ViewController ()
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    
        SecondViewController *second = [[SecondViewController alloc]init];
        
        //设置展示样式(自定义)
        second.modalPresentationStyle = UIModalPresentationCustom;//设置过渡代理(UIPresentationController)
        second.transitioningDelegate = [Transition sharedTransition];
        
        [self presentViewController:second animated:YES completion:nil];
    }
    @end

    演示结果:从右往左进入,接着往左出去

  • 相关阅读:
    HttpClient
    Windows Runtime (RT)
    大败局
    postgresql+postgis+pgrouting实现最短路径查询(1)---线数据的处理和建立拓扑
    postgresql+postgis+pgrouting实现最短路径查询(2)---openlayers+geoserver实现最短路径
    nodejs+postgis实现搜周边
    mac环境下安装posgreSQL,postGIS,pgrouting方法
    postgresql+postgis+pgrouting实现最短路径查询(3)--流程图
    openlayers中的自定制工具栏,包含画点、线、面
    经常用到的23种广告代码。包括图片切换、对联广告等
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4986975.html
Copyright © 2011-2022 走看看