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

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

 

 

posted @ 2015-11-22 22:34  XYQ全哥  阅读(2617)  评论(0编辑  收藏  举报