定制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(, , , )];
_button.backgroundColor = [UIColor blackColor];
_button.layer.cornerRadius = ;
[_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(, , , )];
_button.backgroundColor = [UIColor blackColor];
_button.layer.cornerRadius = ;
[_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(, , -, -); // 设置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(, , -, -); // 管理容器
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操作哦,可以直接去掉即可

定制controller转场动画的更多相关文章

  1. iOS 动画学习之视图控制器转场动画

    一.概述 1.系统会创建一个转场相关的上下文对象,传递到动画执行器的animateTransition:和transitionDuration:方法,同样,也会传递到交互Controller的star ...

  2. iOS - 转场动画

    苹果在 iOS7 定制了 ViewController 的切换效果 一 在iOS5和iOS6之前,ViewController的切换主要有4种 Push/Pop,NavigationViewCotnr ...

  3. iOS 开发--转场动画

    "用过格瓦拉电影,或者其他app可能都知道,一种点击按钮用放大效果实现转场的动画现在很流行,效果大致如下:" 本文主讲SWIFT版,OC版在后面会留下Demo下载 在iOS中,在同 ...

  4. 第六十五篇、OC_iOS7 自定义转场动画push pop

    自定义转场动画,在iOS7及以上的版本才开始出现的,在一些应用中,我们常常需要定制自定义的的跳转动画 1.遵守协议:<UIViewControllerAnimatedTransitioning& ...

  5. 转场动画2-Pop动画

    上一篇试讲push动画,这篇分解pop动画 里面关于矩阵有不懂得,参考CATransform3D 特效详解 上图(虚拟机下,图是渣渣 ) 代码直接上 // // PopTransition.h // ...

  6. iOS自定义转场动画的实现

    iOS中熟悉的是导航栏中的push和pop这两种动画效果,在这里我们可以自己实现自己想要的一些转场动画 下面是我自己创建转场动画的过程 1.新建一个文件继承自NSObject ,遵循协议UIViewC ...

  7. Storyboard 自定义转场动画

    在storyboard中,segue有几种不同的类型,在iphone和ipad的开发中,segue的类型是不同的.在iphone中,segue 有:push,modal,和custom三种不同的类型, ...

  8. iOS 转场动画探究(二)

    这篇文章是接着第一篇写的,要是有同行刚看到的话建议从前面第一篇看,这是第一篇的地址:iOS 转场动画探究(一) 接着上一篇写的内容: 上一篇iOS 转场动画探究(一)我们说到了转场要素的第四点,把那个 ...

  9. iOS转场动画封装

    写在前面 iOS在modal 或push等操作时有默认的转场动画,但有时候我们又需要特定的转场动画效果,从iOS7开始,苹果就提供了自定义转场的API,模态推送present和dismiss.导航控制 ...

随机推荐

  1. elasticsearch插件安装之--拼音插件

    /** * vm12下的centos7.2 * elasticsearch 5.2.2 */ 有时在淘宝搜索商品的时候, 会发现使用汉字, 拼音, 或者拼音混合汉字都会出来想要的搜索结果, 今天找了一 ...

  2. 【云+社区极客说】新一代大数据技术:构建PB级云端数仓实践

    本文来自腾讯云技术沙龙,本次沙龙主题为构建PB级云端数仓实践 在现代社会中,随着4G和光纤网络的普及.智能终端更清晰的摄像头和更灵敏的传感器.物联网设备入网等等而产生的数据,导致了PB级储存的需求加大 ...

  3. 不会几个框架,都不好意思说搞过前端: Node.js & angular.js

    Node.js  菜鸟教程 :http://www.runoob.com/nodejs/nodejs-install-setup.html angular.js  菜鸟教程 :http://www.r ...

  4. kafka 启动 报错cannot allocate memory,即内存不足

    错误提示: Java Hotspot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c5330000, 9865134 ...

  5. Dev中自带添加、编辑、删除等按钮的文字颜色等修改

    下面是ASPxGridView的自带按钮的文字等修改 <SettingsCommandButton> <NewButton Text=" " Image-Tool ...

  6. ABP学习入门系列(一)(第一个ABP项目)

    ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称.ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它 ...

  7. 【JavaScript 从零开始】变量作用域

    变量作用域 一个变量的作用域(scope)是程序源代码中定义这个变量的区域. 全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的.然而在函数内声明的变量只是函数体内有定义. 他 ...

  8. MyEclipse在不同编辑面间快速切换

    想在下面的编辑页面间切换有两种方式,一种是按“栈”方式切换,一种是按“链表”方式切换. 按栈方式切换: Alt + 左箭头: 上一次编辑页面 Alter + 右箭头 : 下一个编辑也页面 按链表(绝对 ...

  9. Java注解(二)

    前面了解了注解的基本内容,这次来看一下自定义注解. 自定义注解其实很简单,直接上代码: import java.lang.annotation.Documented; import java.lang ...

  10. 简单的PHP的任务队列

    文章太长,不作过多介绍,反正,文章的头部就说明了大概的意思...原文如下:写了一个简单的队列任务处理.多进程任务,异步任务可能会用到这个(主要是命令行应用)比如,任务的某个一个环节速度十分不稳定,可能 ...