专栏首页老司机的简书关于自定义modal的转场动画

关于自定义modal的转场动画

效果图

本来是6s的屏幕,转格式的时候被改变了。


模态中,若想实现自定义转场动画,首先应在目标控制器中引入自定义的转场动画类。

然后在目标控制器中设置遵循UIViewControllerTransitionIngDelegate协议。

设置代理

self.transitioningDelegate=self;

为防止内存泄露,同时将模态专场模式设为custom

self.modalPresentationStyle=UIModalPresentationCustom;

实现协议的两个方法,调用自定义的动画。

返回present模式调用的类对象

- (id)animationControllerForPresentedController:(UIViewController*)presented presentingController:(UIViewController*)presenting sourceController:(UIViewController*)source{

return[DDWModalAnimationanimateWithType:(DDWModalAnimationTypePresent)];

}

返回dismiss模式调用的类对象

- (id)animationControllerForDismissedController:(UIViewController*)dismissed{

return[DDWModalAnimationanimateWithType:(DDWModalAnimationTypeDismiss)];

}

只要在目标控制器中设置好专场动画后,源控制器无需做任何操作既能实现自定义专场动画。

只要调用系统的present或者dismiss即可。

经过以上设计,模态跳转页面的时候就可以使用自定义动画了。


关于自定义动画类

首先,创建一个自定义动画类,继承与NSObject。

为了实现模态自定义动画,应遵循协议

为了方便其在目标控制器中返回动画类,建立一个类方法,用来返回类本身。

+(instancetype)DDWAnimateWithType:(DDWModalAnimationType)type;

.m中的实现

定义一个type属性,记录当前为present还是dismiss得状态

首先实现协议中实现动画必须实现的两个方法

返回动画过程的时间

-(NSTimeInterval)transitionDuration:(id)transitionContext

{

return0.5;

}

返回调用模态动画时的具体操作,本例中,将present与dismiss整合到一起,故类中不做具体动画操作,而是根据属性选择对应要执行的动画方法。

-(void)animateTransition:(id)transitionContext

{

switch(self.type) {

caseDDWModalAnimationTypePresent:

{

[selfanimatePresent:transitionContext];

break;

}

caseDDWModalAnimationTypeDismiss:

{

[selfanimateDismiss:transitionContext];

break;

}

default:

break;

}

}

然后实现自定义的类方法。

为了为类本身的属性进行复制,添加init方法

-(instancetype)initAnimateWithType:(DDWModalAnimationType)type

{

self= [superinit];

if(self) {

self.type= type;

}

returnself;

}

+(instancetype)DDWAnimateWithType:(DDWModalAnimationType)type

{

return[[selfalloc]initAnimateWithType:type];

}

然后分别实现两个动画。

上述完成后,已经可以实现自定义模态动画效果了。


同时,ios7.0之后,xcode增加了按照百分比进行模态的功能。可以添加手势,根据手势的偏移量计算是否放弃操作

因为任何情况下,百分比手势的判断原理都是一样的。故将其集中封装在一个管理类中提高复用率。

创建一个管理类,继承与UIPercentDrivenInteractiveTransition

分别添加以下三个属性

记录当前交互状态

@property(assign,nonatomic)BOOLinteration;

为提高复用率,present和push的执行方法均已block形式传入类中。

@property(copy,nonatomic)gestureBlockpresentBlock;

@property(copy,nonatomic)gestureBlockpushBlock;

添加一个初始化管理类的类方法

+(instancetype)DDWInterativeTransitionWithType:(DDWInterativeTransitionType)type

direction:(DDWInterativeTransitionGestureDirection)direction;

添加一个给VC添加手势的实例方法

-(void)addPanGestureForVC:(UIViewController*)VC;

.m中的实现部分

添加三个私有属性,记录当前手势方向,动画类型以及添加手势的控制器。

@property(strong,nonatomic)UIViewController* vc;

@property(assign,nonatomic)DDWInterativeTransitionTypetype;

@property(assign,nonatomic)DDWInterativeTransitionGestureDirectiondirection;

实现类方法

+(instancetype)DDWInterativeTransitionWithType:(DDWInterativeTransitionType)type

direction:(DDWInterativeTransitionGestureDirection)direction{

return[[selfalloc]initInterativeTransitionWithType:typedirection:direction];

}

-(instancetype)initInterativeTransitionWithType:(DDWInterativeTransitionType)type

direction:(DDWInterativeTransitionGestureDirection)direction

{

self= [superinit];

if(self) {

self.type= type;

self.direction= direction;

}

returnself;

}

手势添加方法实现

以上,手势管理者的建立已经完成。在具体的vc中直接引用即可。

源控制器中,添加管理者。

执行顺序,当手势触发是,因为手势种类是present,方向是up,故手势调用block中的方法,从而模态跳转。

之前手势管理者中,已经写好对手势有效性的判断算法,故此时可以对手势的有效性进行判断。

上面已经叙述过,无论何种动画,在源控制器中都不用做相关操作,交由目标控制器去执行动画。故在初始化目标控制器时,将源控制器的管理者传给目标控制器。

目标控制器,同源控制器相同,添加管理者

同时实现手势响应的两个代理,返回present或dismiss操作时返回的交互

效果图

至此,自定义动画以及百分比手势控制便已完成实现。


此处附个人Demo以供日后查看

http://pan.baidu.com/s/1nuTz1Fj

另附原作者Demo,其中共实现模态跳转及nav跳转4种动画,思路相同,不赘述。附上原文链接

http://www.jianshu.com/p/45434f73019e

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 老司机出品———疯狂造轮子之滑动验证码

    消失了好久,大家放心,我还活着。 要问我为什么消失了这么久,如果你知道什么叫封闭开发或许你会懂我。

    老司机Wicky
  • 老司机出品——包教包会之玩转正则表达式

    结束了CoreAnimation系列之后,老司机心里仿佛也轻松了许多。今天说说开发中的一个利器吧,正则表达式。

    老司机Wicky
  • 老司机带你走进Core Animation 之图层的透视、渐变及复制

    老司机的想法就是要把CoreAnimation头文件中的类大概都说一遍,毕竟一开始把系列名定成了《老司机带你走进CoreAnimation》(深切的觉得自己给自...

    老司机Wicky
  • python3 遍历文件下的所有文件

    {'1.jpg': '0', '2.jpg': '0', '3.jpg': '0', '4.jpg': '0', '5.jpg': '0', '6.jpg': ...

    用户2337871
  • 汇编语言-第二章 寄存器(CPU工作原理)之执行指令过程(二)

    青木
  • Redis中String数据类型原理实现

    首先Redis是KV数据结构,跟JDK中的Map是一样的,Redis是通过hashtable实现的,我们把这个叫做外层的哈希,那么每一个KY就是一个entry,...

    用户7386338
  • Hashtable 为什么不叫 HashTable?

    前几天在写《HashMap 和 Hashtable 的 6 个区别》这篇文章的时候,差点把 Hashtable 写成了 HashTable,后来看源码证实了是:...

    Java技术栈
  • 书单推荐 | 12本前端必备书籍

    【作者】Nicholas C.Zakas世界知名的JavaScript专家和Web开发人员。

    疯狂的技术宅
  • 金九银十: 50 个JS 必须懂的面试题为你助力

    Java是一种OOP编程语言, 它创建在虚拟机或浏览器中运行的应用程序, 需要编译Java代码。 JavaScript是一种OOP脚本语言, 代码只在浏览器上...

    Javanx
  • 50 个JS 必须懂的面试题为你助力金九银十

    JavaScript 是一种轻量级的解释型编程语言,具有面向对象的特性,允许各位在其他静态HTML页面中构建交互性。 该语言的通用核心已嵌入Netscape,I...

    前端小智@大迁世界

扫码关注云+社区

领取腾讯云代金券