利用CATransition转场动画, 结合分类特性, 给UINavigationController写一个分类, 在push控制器的时候动点小手脚, 即可实现将整个项目中所有所有push控制器的操作, 添加丰富的转场动画效果...
效果预览图
github地址 https://github.com/CoderPeak/CFPushVCWithCATransition 喜欢的朋友们可以星一个 多谢
之前有人面试, 被问道如何将push控制器的动画做的跟modal效果差不多... 在搜转场动画的时候, 搜到别人的demo(千篇一律的一样,你懂得,只是简单的给view的layer添加动画, 并未给出实际的项目应用场景), 进行改造... 虽然只是进行小改造, 但是, 却在项目中有大用途...
之前看的无数片转场动画的博客, 千篇一律, 都只是简简单单的介绍api的使用(就那么几行代码--核心使用代码不超过10行), 简简单单的搬运... 实在是...
毕竟, 知识要轮回贯通的使用,才能发挥其最大价值, 而不是简单的copy, 而不是简单的copy而不是简单的copy...... 那样只能说明苹果的api好, 而并不能说明你应用的恰当...
简单介绍在项目中应用的思路
- 给UINavigationController写个分类, 为啥? push/pop控制器的操作, 不就是由UINavigationController对象管理的吗?
- 再给其分类添加几个对象方法, 在该对象方法中, 给当前栈顶控制器的view添加转场动画, 再调用本身的系统方法- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated 即可在push控制器的时候, 添加丰富的转场动画
代码简单介绍
- UINavigationController+CATransition.h UINavigationController分类的头文件
// 定义两个枚举 分别是 (目的 --- 因为动画效果众多, 此举可以方便管理动画参数 --- .m文件中有将这些枚举"映射"为系统所需字符串的C函数)
typedef NS_ENUM(NSInteger, CATransitionType) {
CATransitionTypeFade = 1, // 淡化
CATransitionTypeMoveIn, // 覆盖
CATransitionTypePush, // push
CATransitionTypeReveal, // 揭开
CATransitionTypeCube, // 3D立方
CATransitionTypeSuckEffect, // 吮吸
CATransitionTypeOglFlip, // 翻转
CATransitionTypeRippleEffect, // 波纹
CATransitionTypePageCurl, // 翻页
CATransitionTypePageUnCurl, // 反翻页
CATransitionTypeCameraIrisHollowOpen, // 开镜头
CATransitionTypeCameraIrisHollowClose, // 关镜头
};
// 上/下/左/右 4个不同方向的动画
typedef NS_ENUM(NSInteger, CATransitionSubType) {
CATransitionSubTypeFromRight = 1,
CATransitionSubTypeFromLeft,
CATransitionSubTypeFromTop,
CATransitionSubTypeFromBottom
};
// 添加两个对象方法---用于实现控制器跳转, 并加上动画效果
// 动画效果参数传入 字符串
// push
- (void)pushViewController:(UIViewController *)viewController withCATransitionTypeString:(NSString *)typeString subTypeString:(NSString *)subTypeString animated:(BOOL)animated;
// pop
- (void)popViewControllerWithCATransitionTypeString:(NSString *)typeString subTypeString:(NSString *)subTypeString animated:(BOOL)animated;
// 由于字符串并没有提示, 为了方便使用, 再写两个方法, 动画效果参数传枚举, 再"映射"为系统需要的字符串(方便使用---建议使用下面两个方法、就是辣么贴心)
// 传枚举
// push
- (void)pushViewController:(UIViewController *)viewController withCATransitionType:(CATransitionType)type subType:(CATransitionSubType)subType animated:(BOOL)animated;
// pop
- (void)popViewControllerWithCATransitionType:(CATransitionType)type subType:(CATransitionSubType)subType animated:(BOOL)animated;
- UINavigationController+CATransition.m UINavigationController分类的实现文件
// 转场动画持续时间
#define kTransitionDuration 0.8
// 定义一个函数, 传入动画参数的枚举值CATransitionType, 返回系统所真正需要的值---把枚举值映射为系统需要的值
NSString *getCATransitionTypeStringWithCATransitionType(CATransitionType type) {
switch (type) {
case CATransitionTypeFade:
return kCATransitionFade; // 淡化
break;
case CATransitionTypeMoveIn:
return kCATransitionMoveIn; // 覆盖
break;
case CATransitionTypePush:
return kCATransitionPush; // push
break;
case CATransitionTypeReveal:
return kCATransitionReveal; // 揭开
break;
case CATransitionTypeCube:
return @"cube"; // 3D立方
break;
case CATransitionTypeSuckEffect:
return @"suckEffect"; // 吮吸
break;
case CATransitionTypeOglFlip:
return @"oglFlip"; // 翻转
break;
case CATransitionTypeRippleEffect:
return @"rippleEffect"; // 波纹
break;
case CATransitionTypePageCurl:
return @"pageCurl"; // 翻页
break;
case CATransitionTypePageUnCurl:
return @"pageUnCurl"; // 反翻页
break;
case CATransitionTypeCameraIrisHollowOpen:
return @"cameraIrisHollowOpen"; // 开镜头
break;
case CATransitionTypeCameraIrisHollowClose:
return @"cameraIrisHollowClose"; // 关镜头
break;
default:
return @"";
break;
}
}
NSString *getCATransitionSubType(CATransitionSubType subType) {
switch (subType) {
case CATransitionSubTypeFromRight:
return kCATransitionFromRight;
break;
case CATransitionSubTypeFromLeft:
return kCATransitionFromLeft;
break;
case CATransitionSubTypeFromTop:
return kCATransitionFromTop;
break;
case CATransitionSubTypeFromBottom:
return kCATransitionFromBottom;
break;
default:
return @"";
break;
}
}
// 实现自己添加的 带动画的 push控制器的方法
// 动画参数传 系统所需的字符串
- (void)pushViewController:(UIViewController *)viewController withCATransitionTypeString:(NSString *)typeString subTypeString:(NSString *)subTypeString animated:(BOOL)animated
{
CATransition *transition = [CATransition animation];
transition.duration = kTransitionDuration;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = typeString;
transition.subtype = subTypeString;
[self.view.layer addAnimation:transition forKey:@"animation"];
// 添加好动画后 调用系统的push方法 建议animated:后面的参数传NO---都已经用自己添加的转场动画了, 系统本身的push动画方法可以干掉它
[self pushViewController:viewController animated:animated];
}
// 动画参数传 枚举 利用自己写的两个函数 映射为系统所需的字符串参数, 再调用上面的方法
// 建议调用此方法 --- 枚举 有提示 谁不喜欢呢???
- (void)pushViewController:(UIViewController *)viewController withCATransitionType:(CATransitionType)type subType:(CATransitionSubType)subType animated:(BOOL)animated
{
NSString *typeString = getCATransitionTypeStringWithCATransitionType(type);
NSString *subTypeString = getCATransitionSubType(subType);
[self pushViewController:viewController withCATransitionTypeString:typeString subTypeString:subTypeString animated:animated];
}
// pop思路同上
// 实现自己添加的 带动画的 pop控制器的方法
- (void)popViewControllerWithCATransitionTypeString:(NSString *)typeString subTypeString:(NSString *)subTypeString animated:(BOOL)animated
{
CATransition *transition = [CATransition animation];
transition.duration = kTransitionDuration;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = typeString;
transition.subtype = subTypeString;
[self.view.layer addAnimation:transition forKey:@"animation"];
// 添加好动画后 调用系统的pop方法 建议animated:后面的参数传NO---都已经用自己添加的转场动画了, 系统本身的pop动画方法可以干掉它
[self popViewControllerAnimated:animated];
}
- (void)popViewControllerWithCATransitionType:(CATransitionType)type subType:(CATransitionSubType)subType animated:(BOOL)animated
{
NSString *typeString = getCATransitionTypeStringWithCATransitionType(type);
NSString *subTypeString = getCATransitionSubType(subType);
[self popViewControllerWithCATransitionTypeString:typeString subTypeString:subTypeString animated:animated];
}
把这个分类拖到项目中, 自此, 只要想用自定义的转场动画 做项目中的push控制器的动画 只要调用分类中的
// 传枚举(建议)
// push
- (void)pushViewController:(UIViewController *)viewController withCATransitionType:(CATransitionType)type subType:(CATransitionSubType)subType animated:(BOOL)animated;
// pop
- (void)popViewControllerWithCATransitionType:(CATransitionType)type subType:(CATransitionSubType)subType animated:(BOOL)animated;
// 传字符串
// push
- (void)pushViewController:(UIViewController *)viewController withCATransitionTypeString:(NSString *)typeString subTypeString:(NSString *)subTypeString animated:(BOOL)animated;
// pop
- (void)popViewControllerWithCATransitionTypeString:(NSString *)typeString subTypeString:(NSString *)subTypeString animated:(BOOL)animated;
这几个方法即可...
iOS开发的小伙伴们可以看下本人写的其他iOS控件哟
- 直播demo---包含 直播推流/直播拉流/弹幕/美颜/横竖屏/粒子动画/切换摄像头 等主流功能
https://github.com/CoderPeak/CFLive - 一级下拉列表菜单控件 https://github.com/CoderPeak/CFDropDownMenuView
- 多级下拉列表菜单控件 https://github.com/CoderPeak/CFMultistageDropdownMenuView
- 任意位置展示的悬浮框选择控件 https://github.com/CoderPeak/CFPopoverView
- 微信小程序 游戏-贪吃蛇 https://github.com/CoderPeak/---snakeGame