首先,支持并感谢@wazrx 的 http://www.jianshu.com/p/45434f73019e和@onevcathttps://onevcat.com/2013/10/vc-transition-in-ios7/ 对于转场动画的讲解和实现,非常详细,本人也是看过他们的文章后受的启发,快速实现了基于本项目需求的转场动画效果。

效果如下:(gif是我们的美术大师帮忙做的演示动效,实际的效果要比这个好,可通过文章最后链接下载我们的app:柠檬跑步,查看效果)

地图切换.gif

我的需求是两个页面push、pop之间的切换,所以自定义了push的转场动画,首先需要个遵循<UIViewControllerAnimatedTransitioning>协议的管理对象,并实现其两个方法:
XWCircleSpreadTransition.h

#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, XWCircleSpreadTransitionType) {    
   XWCircleSpreadTransitionTypePush = 0,    
   XWCircleSpreadTransitionTypePop
};
@interface XWCircleSpreadTransition : NSObject<UIViewControllerAnimatedTransitioning>
@property (nonatomic, assign) XWCircleSpreadTransitionType type;  
+ (instancetype)transitionWithTransitionType:(XWCircleSpreadTransitionType)type;
- (instancetype)initWithTransitionType:(XWCircleSpreadTransitionType)type;@end

XWCircleSpreadTransition.m

#import "XWCircleSpreadTransition.h"
@implementation XWCircleSpreadTransition
+ (instancetype)transitionWithTransitionType:(XWCircleSpreadTransitionType)type{    
   return [[self alloc] initWithTransitionType:type];
}  
- (instancetype)initWithTransitionType:(XWCircleSpreadTransitionType)type{    
   self = [super init];    
   if (self) {        
        _type = type;    
   }    
   return self;
}  
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{    
   return 0.7;
}  
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{    
   switch (_type) {        
       case XWCircleSpreadTransitionTypePush:            
           [self presentAnimation:transitionContext];            
           break;        
       case XWCircleSpreadTransitionTypePop:            
           [self dismissAnimation:transitionContext];            
           break;    
    }
}  
- (void)dismissAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{    
   UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];    
   UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];    
   UIView *containerView = [transitionContext containerView];    
   [containerView insertSubview:toVC.view atIndex:0];    //画两个圆路径    
   CGFloat radius = sqrtf(containerView.frame.size.height * containerView.frame.size.height + containerView.frame.size.width * containerView.frame.size.width) / 2;    UIBezierPath *startCycle = [UIBezierPath bezierPathWithArcCenter:containerView.center radius:radius startAngle:0 endAngle:M_PI * 2 clockwise:YES];//    UIBezierPath *endCycle =  [UIBezierPath bezierPathWithOvalInRect:temp.mapBtnFrame];    
   UIBezierPath *endCycle =  [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 0, 0)];    //创建CAShapeLayer进行遮盖    
   CAShapeLayer *maskLayer = [CAShapeLayer layer];    
   maskLayer.fillColor = [UIColor greenColor].CGColor;    
   maskLayer.path = endCycle.CGPath;    
   fromVC.view.layer.mask = maskLayer;    //创建路径动画    
   CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"path"];    
   maskLayerAnimation.delegate = self;    
   maskLayerAnimation.fromValue = (__bridge id)(startCycle.CGPath);    
   maskLayerAnimation.toValue = (__bridge id)((endCycle.CGPath));    
   maskLayerAnimation.duration = [self transitionDuration:transitionContext];    
   maskLayerAnimation.delegate = self;    
   maskLayerAnimation.timingFunction = [CAMediaTimingFunction  functionWithName:kCAMediaTimingFunctionEaseInEaseOut];    
   [maskLayerAnimation setValue:transitionContext forKey:@"transitionContext"];    
   [maskLayer addAnimation:maskLayerAnimation forKey:@"path"];
}  
- (void)presentAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];    UIView *containerView = [transitionContext containerView];    
   [containerView addSubview:toVC.view];    //画两个圆路径//    UIBezierPath *startCycle =  [UIBezierPath bezierPathWithOvalInRect:fromVC.mapBtnFrame];    
   UIBezierPath *startCycle =  [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 0, 0)];    CGFloat x = MAX(100, containerView.frame.size.width - 100);    CGFloat y = MAX(100, containerView.frame.size.height - 100);    CGFloat radius = sqrtf(pow(x, 2) + pow(y, 2));    UIBezierPath *endCycle = [UIBezierPath bezierPathWithArcCenter:containerView.center radius:radius startAngle:0 endAngle:M_PI * 2 clockwise:YES];    //创建CAShapeLayer进行遮盖    
   CAShapeLayer *maskLayer = [CAShapeLayer layer];    
   maskLayer.path = endCycle.CGPath;    //将maskLayer作为toVC.View的遮盖    
   toVC.view.layer.mask = maskLayer;    //创建路径动画    
   CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"path"];    
   maskLayerAnimation.delegate = self;    //动画是加到layer上的,所以必须为CGPath,再将CGPath桥接为OC对象    
   maskLayerAnimation.fromValue = (__bridge id)(startCycle.CGPath);    
   maskLayerAnimation.toValue = (__bridge id)((endCycle.CGPath));    
   maskLayerAnimation.duration = [self transitionDuration:transitionContext];    
   maskLayerAnimation.delegate = self;    
   maskLayerAnimation.timingFunction = [CAMediaTimingFunction  functionWithName:kCAMediaTimingFunctionEaseInEaseOut];      
   [maskLayerAnimation setValue:transitionContext forKey:@"transitionContext"];    
   [maskLayer addAnimation:maskLayerAnimation forKey:@"path"];
}  
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{    
   switch (_type) {        
       case XWCircleSpreadTransitionTypePush:{            
           id<UIViewControllerContextTransitioning> transitionContext = [anim valueForKey:@"transitionContext"];             [transitionContext completeTransition:YES];            
           UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];            
           toView.layer.mask = nil;            
           UIViewController *vc = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];             vc.view.layer.mask = nil;         }            
           break;        
       case XWCircleSpreadTransitionTypePop:{            
           id<UIViewControllerContextTransitioning> transitionContext = [anim valueForKey:@"transitionContext"];            
           [transitionContext completeTransition:YES];            
           UIViewController *vc = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];            
           vc.view.layer.mask = nil;         }            
           break;    
   }
}
@end

剩下的就是在ViewControllerA中实现代理<UINavigationControllerDelegate>中的animationControllerForOperation:

#pragma mark -
#pragma mark - UINavigation Delegate
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {    
   if (fromVC == self) {        
       return [XWCircleSpreadTransition transitionWithTransitionType:XWCircleSpreadTransitionTypePush];    
   }    
   if (toVC == self) {        
       return [XWCircleSpreadTransition transitionWithTransitionType:XWCircleSpreadTransitionTypePop];    
   }    
   return nil;
}
 

到此,这个简单的转场动画已经实现完毕,而且动画效果可以自定义成自己想要的展现形式。

类似nike+、香蕉打卡的转场动画效果-b的更多相关文章

  1. iOS CATransition 自定义转场动画

    https://www.jianshu.com/p/39c051cfe7dd CATransition CATransition 是CAAnimation的子类(如下图所示),用于控制器和控制器之间的 ...

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

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

  3. 自己定义转场动画--Swift3.0版本号

    转场动画这事.说简单也简单.能够通过presentViewController:animated:completion:和dismissViewControllerAnimated:completio ...

  4. ios基础动画、关键帧动画、动画组、转场动画等

    概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画 ...

  5. iOS自定义转场动画实战讲解

    iOS自定义转场动画实战讲解   转场动画这事,说简单也简单,可以通过presentViewController:animated:completion:和dismissViewControllerA ...

  6. 超酷炫的转场动画?CSS 轻松拿下!

    在 WeGame 的 PC 端官网首页,有着非常多制作精良的基于滚动的动画效果. 这里我简单截取其中 2 个比较有意思的转场动画,大家感受感受.转场动画 1: 转场动画 2: 是不是挺有意思的,整个动 ...

  7. iOS开发UI篇—核心动画(转场动画和组动画)

    转自:http://www.cnblogs.com/wendingding/p/3801454.html iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的 ...

  8. CATransition-转场动画

    CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果.iOS比Mac OS X的转场动画效果少一点 UINavigationController就是通过CATrans ...

  9. iOS:核心动画之转场动画CATransition

    转场动画——CATransition CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果.iOS比Mac OS X的转场动画效果少一点 U ...

随机推荐

  1. 关于关闭Eclipse的控制台自动跳出

    参考文章: http://my.oschina.net/mn1127/blog/161093 Eclipse的控制台console有时候经常的跳出来,非常的烦人! 尤其是在调试期间跳出,以下是分享一下 ...

  2. [未完成]关于POI的使用

    关于POI的使用关于POI的使用关于POI的使用关于POI的使用

  3. The message queue

    今晚来整理一下消息队列,消息队列是一条由消息连接而成的链表,存在内核里面,通过消息对了的引用标识符来访问,每个消息队列都有一个msqid_ds结构与之对应,这个结构保存了消息队列的当前状态参数,这个结 ...

  4. org.json 使用

    org.json 和 json-lib 使用上差不多. //JSONObject public static void main(String[] args) { String jsonObjectS ...

  5. js中关于事件处理函数名后面是否带括号的问题

    今天总结一个关于事件处理程序的小细节.首先回顾一下事件处理的一些概念. JS中的事件处理(事件绑定)就是让某种或某些事件触发某些活动.有两种常见的形式,分别是DOM Level 0 和DOM Leve ...

  6. fadein()

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. SQL Server 查询分析器提供的所有键盘快捷方式(转)

    下表列出 SQL Server 查询分析器提供的所有键盘快捷方式. 活动 快捷方式 书签:清除所有书签. CTRL-SHIFT-F2 书签:插入或删除书签(切换). CTRL+F2 书签:移动到下一个 ...

  8. Oracle学习第二天---Profile的使用

    环境:Oracle 11g 一.权限的传递 1.如果传递的是对象权限,就在后面加入with grant option: eg:system用户有张temp的表,只想usertest用户拥有查询的权限, ...

  9. 第十一篇、RxSwift

    三. 什么是函数式编程? 什么是函数式编程呢? 函数式编程其实是一种编程思想, 代码写出来只是它的表现形式. 在面向对象的编程思想中, 我们将要解决的一个个问题, 抽象成一个个类, 通过给类定义属性和 ...

  10. 实例介绍Cocos2d-x物理引擎:HelloPhysicsWorld

    我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用物理引擎的开发过程,熟悉这些API的使用.这个实例的运行后的场景,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触摸点生成一个新的 ...