定制controller转场动画

简介:

定制controller转场动画

 

从iOS7开始就可以自由定制控制器间的转场动画了,以下实例描述最简单的定制方式,达到的效果如下所示:

为了实现这个效果需要这么多的文件-_-!!!!

RootViewController

//
//  RootViewController.h
//  ControllerCustom
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController

@end

RootViewController.h


//
//  RootViewController.m
//  ControllerCustom
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"

#import "PresentingAnimator.h"
#import "DismissingAnimator.h"

#import "ModelViewController.h"

@interface RootViewController ()<UIViewControllerTransitioningDelegate>

@property (nonatomic, strong) UIButton *button;

@end

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor cyanColor];
    
    _button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
    _button.backgroundColor = [UIColor blackColor];
    _button.layer.cornerRadius = 5;
    [_button setTitle:@"present"
             forState:UIControlStateNormal];
    _button.center = self.view.center;
    [self.view addSubview:_button];
    
    [_button addTarget:self
                action:@selector(buttonEvent:)
      forControlEvents:UIControlEventTouchUpInside];
}

- (void)buttonEvent:(id)sender
{
    // 推出控制器
    ModelViewController *modalViewController = [ModelViewController new];
    
    // 设置转场动画代理
    modalViewController.transitioningDelegate = self;
    
    // 定制转场动画
    modalViewController.modalPresentationStyle = UIModalPresentationCustom;
    
    [self presentViewController:modalViewController
                       animated:YES
                     completion:NULL];
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                  presentingController:(UIViewController *)presenting
                                                                      sourceController:(UIViewController *)source
{
    // 推出控制器的动画
    return [PresentingAnimator new];
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    // 退出控制器动画
    return [DismissingAnimator new];
}

@end

RootViewController.m

ModelViewController
//
//  ModelViewController.h
//  ControllerCustom
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ModelViewController : UIViewController

@end

ModelViewController.h


//
//  ModelViewController.m
//  ControllerCustom
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "ModelViewController.h"

@interface ModelViewController ()

@property (nonatomic, strong) UIButton *button;

@end

@implementation ModelViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blueColor];
    
    _button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
    _button.backgroundColor = [UIColor blackColor];
    _button.layer.cornerRadius = 5;
    [_button setTitle:@"dismiss"
             forState:UIControlStateNormal];
    _button.center = self.view.center;
    [self.view addSubview:_button];
    
    [_button addTarget:self
                action:@selector(buttonEvent:)
      forControlEvents:UIControlEventTouchUpInside];
}

- (void)buttonEvent:(id)sender
{
    [self dismissViewControllerAnimated:YES
                             completion:^{
                                 
                             }];
}

@end

ModelViewController.m

PresentingAnimator
//
//  PresentingAnimator.h
//  ControllerCustom
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface PresentingAnimator : NSObject<UIViewControllerAnimatedTransitioning>

@end

PresentingAnimator.h


//
//  PresentingAnimator.m
//  ControllerCustom
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "PresentingAnimator.h"

@implementation PresentingAnimator

// 转场动画时间
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    // 自己的view
    UIView *fromView = \
        [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
    
    // 另一个view
    UIView *toView   = \
        [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
    
    // 管理容器
    UIView *container = [transitionContext containerView];
    container.backgroundColor = [UIColor blackColor];
    
    // 容器中添加推出的view
    [container addSubview:fromView];
    [container addSubview:toView];
    
    // 开始动画(移出fromView,移进toView)
    [UIView animateWithDuration:[self transitionDuration:transitionContext]
                     animations:^{                         
                         fromView.frame = CGRectMake(10, 10, 320-20, 568-20);
                         
                         // 设置toView从右侧偏移进来
                         CGRect toFrame     = toView.frame;
                         toFrame.origin.x   = container.bounds.size.width; // 偏移一个控制器
                         toView.frame = toFrame;
                         toView.center = container.center;
                         
                     } completion:^(BOOL finished) {
                         // 动画结束
                         [transitionContext completeTransition:YES];
                     }];
}

@end

 PresentingAnimator.m

DismissingAnimator
//
//  DismissingAnimator.h
//  Popping
//
//  Created by André Schneider on 16.05.14.
//  Copyright (c) 2014 André Schneider. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface DismissingAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

DismissingAnimator.h


//
//  DismissingAnimator.m
//  Popping
//
//  Created by André Schneider on 16.05.14.
//  Copyright (c) 2014 André Schneider. All rights reserved.
//

#import "DismissingAnimator.h"

@implementation DismissingAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    // 自己的view
    UIView *fromView = \
    [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
    
    // 另一个view
    UIView *toView   = \
    [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
    toView.frame = CGRectMake(10, 10, 320-20, 568-20);

    
    // 管理容器
    UIView *container = [transitionContext containerView];
    
    
    // 容器中添加推出的view
    [container addSubview:toView];
    [container addSubview:fromView];
    
    container.backgroundColor = [UIColor blackColor];
    
    // 开始动画(移出fromView,移进toView)
    [UIView animateWithDuration:[self transitionDuration:transitionContext]
                     animations:^{
                         CGRect fromFrame = fromView.frame;
                         fromFrame.origin.x = container.bounds.size.width;
                         fromView.frame = fromFrame;
                        
                         toView.frame = container.frame;

                     } completion:^(BOOL finished) {
                         // 动画结束
                         [transitionContext completeTransition:YES];
                     }];
}

@end

DismissingAnimator.m

核心的地方:

为什么设计成代理呢?其实,这是为了让基本的控制器(推出其他控制器的控制器)持有被推出的控制器而已,我是这么理解的.

 

为了能够实现控制器间的转场动画,我们需要一个实现了UIViewControllerAnimatedTransitioning协议的对象才行.

也就是PresentingAnimator以及DismissingAnimator

最少实现里面的两个方法:

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

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

完了,就是这么简单呢.

 

附录:

这个方法非常关键哦,动画执行完了之后记得设置好了.

 

fromView本身就被transitionContext包含拥有了,你无须进行上面的那个addSubview操作哦,可以直接去掉即可

目录
相关文章
UINavigationController获取上一级Controller
UINavigationController获取上一级Controller
50 0
|
小程序 容器
讲述小程序之组件视图容器之scroll-view(可滚动视图)
讲述小程序之组件视图容器之scroll-view(可滚动视图)
182 0
讲述小程序之组件视图容器之scroll-view(可滚动视图)
|
容器
(一)UINavigationController(导航控制器)的详解
(一)UINavigationController(导航控制器)的详解
336 0
|
Web App开发 JavaScript 前端开发
SAP UI5 视图控制器 View Controller 的生命周期方法 - Lifecycle methods
SAP UI5 视图控制器 View Controller 的生命周期方法 - Lifecycle methods
SAP UI5 视图控制器 View Controller 的生命周期方法 - Lifecycle methods
|
iOS开发
iOS开发中标签控制器的使用——UITabBarController(一)
iOS开发中标签控制器的使用——UITabBarController
201 0
iOS开发中标签控制器的使用——UITabBarController(一)
|
iOS开发
iOS开发中标签控制器的使用——UITabBarController(二)
iOS开发中标签控制器的使用——UITabBarController
289 0
|
图形学
Unity动画机制 Animator与Animator Controller教程
Unity动画机制Animator 本文提供全流程,中文翻译。 Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) Chinar —.
4269 0