一、创建一个UIViewController的分类即可:
1、h文件
#import <UIKit/UIKit.h>
typedef NS_ENUM (NSInteger, ZJPushType) {
//push
leftToRight = 1,
centerToEdge = 3,
topToBottom = 5,
diagonalEnlarge = 7,
// pop
rightToLeft = 2,
edgeToCenter = 4,
bottomToTop = 6,
diagonalNarrow = 8,
};
#import <Foundation/Foundation.h>
@interface ZJPushAnimation : NSObject<UIViewControllerAnimatedTransitioning>
-(instancetype)initWithPushType:(ZJPushType)type;
@end
typedef NS_ENUM (NSInteger, ZJStartOrEndPath) {
startPath = 1,
endPath = 2,
};
@interface UIViewController (PushAnimation)
-(void)pushViewController:(UIViewController *)viewController animation:(ZJPushType)animation;
-(UIViewController *)popViewControllerAnimation:(ZJPushType)animation;
@end
2、m文件
#import "UIViewController+PushAnimation.h"
#import <objc/runtime.h>
@interface UIViewController ()<UINavigationControllerDelegate>
@property(nonatomic,assign) ZJPushType animation;
@end
@implementation UIViewController (PushAnimation)
-(void)setAnimation:(ZJPushType)animation{
objc_setAssociatedObject(self, @selector(animation), @(animation), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(ZJPushType)animation{
return [objc_getAssociatedObject(self, @selector(animation)) integerValue];
}
-(void)pushViewController:(UIViewController *)viewController animation:(ZJPushType)animation{
self.navigationController.delegate = self;
[self setAnimation:animation];
[self.navigationController pushViewController:viewController animated:YES];
}
-(UIViewController *)popViewControllerAnimation:(ZJPushType)animation{
self.navigationController.delegate = self;
[self setAnimation:animation];
return [self.navigationController popViewControllerAnimated:YES];
}
#pragma mark -- UINavigationControllerDelegate --
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
self.navigationController.delegate = nil;
return [[ZJPushAnimation alloc] initWithPushType:self.animation];
}
-(void)dealloc{
self.navigationController.delegate = nil;
}
@end
@interface ZJPushAnimation()<CAAnimationDelegate>
@property (nonatomic, strong)id<UIViewControllerContextTransitioning> transitionContext;
@property(nonatomic,assign) ZJPushType pushType;
@end
@implementation ZJPushAnimation
#pragma mark -- UIViewControllerAnimatedTransitioning --
-(instancetype)initWithPushType:(ZJPushType)type{
if(self == [super init]){
self.pushType = type;
}
return self;
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return 0.3;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
self.transitionContext = transitionContext;
//获取源控制器 注意不要写成 UITransitionContextFromViewKey
UIViewController *fromVc = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
//获取目标控制器 注意不要写成 UITransitionContextToViewKey
UIViewController *toVc = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
//获得容器视图
UIView *containView = [transitionContext containerView];
// 都添加到container中。注意顺序 目标控制器的view需要后面添加
if(self.pushType%2 == 1){
[containView addSubview:fromVc.view];
[containView addSubview:toVc.view];
}else{
[containView addSubview:toVc.view];
[containView addSubview:fromVc.view];
}
//
UIBezierPath *startPath = [self pathWithPushType:self.pushType StartOrEnd:1];
UIBezierPath *endPath = [self pathWithPushType:self.pushType StartOrEnd:2];
//赋值给toVc视图layer的mask
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = endPath.CGPath;
if(self.pushType%2 == 1)toVc.view.layer.mask = maskLayer;
if(self.pushType%2 == 0)fromVc.view.layer.mask = maskLayer;
CABasicAnimation *maskAnimation =[CABasicAnimation animationWithKeyPath:@"path"];
maskAnimation.fromValue = (__bridge id)startPath.CGPath;
maskAnimation.toValue = (__bridge id)endPath.CGPath;
maskAnimation.duration = [self transitionDuration:transitionContext];
maskAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
maskAnimation.delegate = self;
[maskLayer addAnimation:maskAnimation forKey:@"path"];
}
#pragma mark -- CAAnimationDelegate --
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
//告诉 iOS 这个 transition 完成
[self.transitionContext completeTransition:YES];
[self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
[self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
}
#pragma mark - Animations
/**
* @prarm pushType 跳转类型
* @prarm pathType 开始或者结尾
*/
-(UIBezierPath *)pathWithPushType:(ZJPushType)pushType StartOrEnd:(ZJStartOrEndPath)pathType{
CGSize screenSize = [UIScreen mainScreen].bounds.size;
UIBezierPath * path = [UIBezierPath bezierPath];
if(pushType == 1){ // leftToRight
if(pathType == 1){
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 1, screenSize.height)];
}else{
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];
}
}else if(pushType == 2){ // rightToLeft
if(pathType == 1){
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];
}else{
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 1, screenSize.height)];
}
}else if(pushType == 3){ // centerToEdge
CGRect subFrame = CGRectMake(screenSize.width*0.5, screenSize.height*0.5, 0, 0);
if(pathType == 1){
path = [UIBezierPath bezierPathWithOvalInRect:subFrame];
}else{
CGFloat radius = sqrt(screenSize.width*0.5*screenSize.width*0.5+screenSize.height*0.5*screenSize.height*0.5);
path = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(subFrame, -radius, -radius)];
}
}else if(pushType == 4){ // edgeToCenter
CGSize screenSize = [UIScreen mainScreen].bounds.size;
CGRect subFrame = CGRectMake(screenSize.width*0.5, screenSize.height*0.5, 0, 0);
if(pathType == 1){
// sqrt函数表示开平方根
CGFloat radius = sqrt(screenSize.width*0.5*screenSize.width*0.5+screenSize.height*0.5*screenSize.height*0.5);
path = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(subFrame, -radius, -radius)];
}else{
//绘制圆形
path = [UIBezierPath bezierPathWithOvalInRect:subFrame];
}
}else if(pushType == 5){ // topToBottom
if(pathType == 1){
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, 1)];
}else{
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];
}
}else if(pushType == 6){ // bottomToTop
if(pathType == 1){
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];
}else{
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, 1)];
}
}else if(pushType == 7){ // diagonalEnlarge
if(pathType == 1){
path = [UIBezierPath bezierPathWithRect:CGRectMake(screenSize.width, screenSize.height, 0, 0)];
}else{
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];
}
}else if(pushType == 8){ // diagonalNarrow
if(pathType == 1){
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];
}else{
path = [UIBezierPath bezierPathWithRect:CGRectMake(screenSize.width, screenSize.height,0, 0)];
}
}
return path;
}
@end