Ping转场动画的实现之二:转场动画

上次说了一下mask,,这次来讲一下如何用mask来实现这个动画,关于自定义转场动画的内容可以查看这篇文章,要实现的动画如下:

首页实现两个viewcontroller之间的push和pop,示例代码如下:

第一个viewcontroller

– (void)viewDidLoad {[super viewDidLoad];//设置背景色self.view.backgroundColor = [UIColor greenColor];//放一张图片UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 300)];imageView.center = self.view.center;imageView.image = [UIImage imageNamed:@"ipad.jpg"];[self.view addSubview:imageView];//创建按钮_btn = [UIButton buttonWithType:UIButtonTypeCustom];_btn.backgroundColor = [UIColor blackColor];_btn.layer.cornerRadius = 22;_btn.frame = CGRectMake(self.view.frame.size.width-20-44, 20, 44, 44);[_btn addTarget:self action:@selector(goNext) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:_btn];}//push到下一个- (void)goNext{SecondViewController *sec = [[SecondViewController alloc]init];[self.navigationController pushViewController:sec animated:YES];}第二个viewcontroller:- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor yellowColor];UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 300)];imageView.center = self.view.center;imageView.image = [UIImage imageNamed:@"iphone.jpg"];[self.view addSubview:imageView];_btn = [UIButton buttonWithType:UIButtonTypeCustom];_btn.backgroundColor = [UIColor blackColor];_btn.layer.cornerRadius = 22;_btn.frame = CGRectMake(self.view.frame.size.width-20-44, 20, 44, 44);[_btn addTarget:self action:@selector(goBack) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:_btn];}- (void)goBack{[self.navigationController popViewControllerAnimated:YES];}效果如下:

让这两个viewcontroller遵守

@interface ViewController ()<UINavigationControllerDelegate>@interface SecondViewController ()<UINavigationControllerDelegate>都设置好代理:- (void)viewWillAppear:(BOOL)animated{self.navigationController.delegate = self;}- (void)viewWillDisappear:(BOOL)animated{self.navigationController.delegate = nil;}都实现协议方法(返回一个自定义动画对象):- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{return myAnimation;}接下来就是创建这个自定义的动画对象,创建一个类,遵守//.h#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>@interface CircleAnimation : NSObject <UIViewControllerAnimatedTransitioning>@end//.m#import "CircleAnimation.h"#import "ViewController.h"#import "SecondViewController.h"@interface CircleAnimation ()@property (assign, nonatomic) id <UIViewControllerContextTransitioning> context;@end@implementation CircleAnimation- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{return 3.0;}- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{//得到上下文self.context = transitionContext;//获取容器视图UIView *container = [transitionContext containerView];//获取参与转场的viewcontrollerUIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];//拿到btn,需要用到他的frameUIButton *btn;if ([fromVC isKindOfClass:[ViewController class]]) {btn = ((ViewController*)fromVC).btn;}else if ([fromVC isKindOfClass:[SecondViewController class]]) {btn = ((SecondViewController*)fromVC).btn;}[container addSubview:toVC.view];//起始路径UIBezierPath *initPath = [UIBezierPath bezierPathWithOvalInRect:btn.frame];//大圆半径CGFloat newR = sqrt(btn.center.x*btn.center.x + (btn.center.y-CGRectGetHeight(toVC.view.bounds))*(btn.center.y-CGRectGetHeight(toVC.view.bounds)));//终点路径UIBezierPath *finalPath = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(btn.frame, -newR, -newR)];//创建一个遮罩CAShapeLayer *maskLayer = [CAShapeLayer layer];maskLayer.path = [finalPath CGPath];toVC.view.layer.mask = maskLayer;//创建动画CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];animation.fromValue = (__bridge id)([initPath CGPath]);animation.toValue = (__bridge id)([finalPath CGPath]);animation.duration = [self transitionDuration:transitionContext];animation.delegate = self;//添加动画[maskLayer addAnimation:animation forKey:@"path"];}//清理工作- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{[self.context viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;[self.context viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;[self.context completeTransition:![self.context transitionWasCancelled]];}@end在两个viewcontroller里创建该动画对象,并在实现的协议方法里,返回它:- (void)viewDidLoad {[super viewDidLoad];_ani = [[CircleAnimation alloc]init];//设置背景色….}- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{return _ani;}run!

微笑的去寻找一个不可能出现的你。

Ping转场动画的实现之二:转场动画

相关文章:

你感兴趣的文章:

标签云: